英文:
Format a string to have the same spaces as another string in python
问题
如果我有两个相同长度的字符串:
```python
foo = "foofoo foo fo o"
abc = "abcabcabcabc"
我想要能够做到这样:
func(abc,foo)
> "abcabc abc ab c"
我知道我可以通过检查第一个字符串中的空格位置,并在另一个字符串中相同的位置插入空格(考虑到之前添加的空格)来实现这一点,但是否有更直接和高效的方法?
<details>
<summary>英文:</summary>
If I have two strings of same length :
foo = "foofoo foo fo o"
abc = "abcabcabcabc"
I would like to be able to have something like this
func(abc,foo)
> "abcabc abc ab c"
I know I might be able to do this by checking where the spaces are in the first string and insert spaces at the same place in the other (taking into account the previously added ones), but is there something more direct and efficient ?
</details>
# 答案1
**得分**: 0
不要试图通过改变字符串来实现这个,我建议通过同时迭代两个字符串并构建一个新字符串来实现:
```python
>>> def func(a, b):
... j = 0
... ret = ""
... for x in a:
... if x.isspace():
... ret += x
... else:
... ret += b[j]
... j += 1
... return ret
...
>>> func("foofoo foo fo o", "abcabcabcabc")
'abcabc abc ab c'
英文:
Rather than trying to do this by mutating the string, I'd suggest doing it by iterating over both strings in parallel and building a new string:
>>> def func(a, b):
... j = 0
... ret = ""
... for x in a:
... if x.isspace():
... ret += x
... else:
... ret += b[j]
... j += 1
... return ret
...
>>> func("foofoo foo fo o", "abcabcabcabc")
'abcabc abc ab c'
答案2
得分: 0
这里是代码的翻译部分:
foo = "foofoo foo fo o"
abc = "abcabcabcabc"
def manip(origin: str, pattern: str) -> str:
comp: str = ""
i: int = 0
for p in pattern:
comp += " " if p == " " else origin[i]
if p != " ": i += 1
return comp
print(manip(abc, foo))
请注意,我只翻译了代码部分,其他内容保持不变。
英文:
Maybe something like this:
foo = "foofoo foo fo o"
abc = "abcabcabcabc"
def manip(origin: str, pattern: str) -> str:
comp: str = ""
i: int = 0
for p in pattern:
comp += " " if p == " " else origin[i]
if p != " ": i += 1
return comp
print(manip(abc,foo))
答案3
得分: 0
def match_spaces(s1, s2):
it = iter(s2)
return ' '.join(l if l.isspace() else next(it) for l in s1)
match_spaces(foo, abc)
# 'a b c a b c a b c a b c'
英文:
You could make an iterator out of the second string and yield values where s1 is not a space otherwise the next letter:
foo = "foofoo foo fo o"
abc = "abcabcabcabc"
def match_spaces(s1, s2):
it = iter(s2)
return ' '.join(l if l.isspace() else next(it) for l in s1)
match_spaces(foo, abc)
# 'a b c a b c a b c a b c'
答案4
得分: 0
你可以使用 re.finditer()
来查找空格的位置,然后从这些索引构建字符串:
import re
from itertools import tee
foo = "foofoo foo fo o"
abc = "abcdefghijkl"
spans = []
pos = 0
a_start, a_end = (0, 0)
for m in re.finditer(" ", foo):
b_start, b_end = m.span()
spans.append(abc[pos:pos + b_start - a_end])
spans.append(m.group())
pos += b_start - a_end
a_start, a_end = b_start, b_end
spans.append(abc[pos:])
print("".join(spans))
或者,如果你可以将分割模式表示为负正则表达式,你可以使用 itertools 来优雅地表达它:
import re
from itertools import chain, tee, accumulate, pairwise
foo = "foofoo foo fo o"
abc = "abcdefghijkl"
matches = list(re.finditer("[^ ]+", foo))
lens = (m.end() - m.start() for m in matches)
accs = accumulate(lens, initial=0)
indices = pairwise(accs)
result = " ".join([abc[a:z] for m, (a, z) in zip(matches, indices)])
print(result)
pairwise 在 Python 3.10 及以上版本可用,accumulate 自 Python 3.2 可用,但 initial
参数是 Python 3.8 中新增的。有关适用于旧版本 Python 的等效实现,请参阅 itertools 文档。
英文:
You can use re.finditer()
to find the position of spaces, and then just build the string from the indices:
import re
from itertools import tee
foo = "foofoo foo fo o"
abc = "abcdefghijkl"
spans = []
pos = 0
a_start, a_end = (0, 0)
for m in re.finditer(" ", foo):
b_start, b_end = m.span()
spans.append(abc[pos:pos + b_start - a_end])
spans.append(m.group())
pos += b_start - a_end
a_start, a_end = b_start, b_end
spans.append(abc[pos:])
print("".join(spans))
Alternatively, if you can express the split pattern as a negative regex, you can express this very elegantly using itertools instead:
import re
from itertools import chain, tee, accumulate, pairwise
foo = "foofoo foo fo o"
abc = "abcdefghijkl"
matches = list(re.finditer("[^ ]+", foo))
lens = (m.end() - m.start() for m in matches)
accs = accumulate(lens, initial=0)
indices = pairwise(accs)
result = " ".join([abc[a:z] for m, (a, z) in zip(matches, indices)])
print(result)
pairwise is available on Python 3.10 upwards, accumulate is available since Python 3.2, but the initial
argument is new in Python 3.8. Refer to itertools documentations for equivalent implementation suitable for older Python.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论