用Python将字符串拆分并保存到列表中

3

我有一个字符串,我在其中各个位置插入了空格并将其保存到列表中。现在,我想将这些带有空格的字符串拆分并将输出放入一个列表中,但这样做会导致多个列表存在:

以下是我正在处理的代码:

var ='sans'
res = [var[:i]+' '+var[i:] for i in range(len(var))]
// The previous line: AM adding a space to see maybe that would generate other words
cor = [res[i].split() for i in range (len(res))]

这是我得到的输出结果:
>>> cor
[['sans'], ['s', 'ans'], ['sa', 'ns'], ['san', 's']]

What am expecting:

>>> cor
    ['sans', 's', 'ans', 'sa', 'ns', 'san', 's']

我是一名初学 Python 的新手,不知道自己还有哪些掌握不足。

谢谢。

5个回答

6

一种替代方案:

cor = " ".join(res).split()

输出:

['sans', 's', 'ans', 'sa', 'ns', 'san', 's']

说明

" ".join(res) 将在res中的每个字符串之间加上一个空格进行连接。然后调用 .split() 会将这个字符串按照空格分割成列表。

编辑:第二种方法不涉及中间变量res,但这种方法看起来没有那么容易理解:

cor = [var[:i/2+1] if i%2==1 else var[i/2:] for i in range(2*len(var)-1)]

基本上,你需要在前面和后面建立子字符串来翻转。

@StefanPochmann 哈哈,别开玩笑了,这得用 timeit 来测试一下,因为我认为这个答案甚至比列表推导式更简单 :P - roganjosh
@StefanPochmann正在为此构建一个测试平台,但我认为关于空格的观察也是完全有效的。 - roganjosh
1
@roganjosh 但它比我们的快得多。 - Stefan Pochmann
@StefanPochmann 我设置了这个用于测试。显然我无法正确阅读%timeit的输出,所以最好检查一下,因为我混淆了毫秒和纳秒。 - roganjosh
1
@roganjosh 嗯,你在那里犯了一个大错误。我的拼法不是“ph”:-)。而且,没有时间代码,只有解决方案。 - Stefan Pochmann
显示剩余14条评论

3
首先,你的
[res[i].split() for i in range (len(res))]

这是一种复杂的非 Pythonic 的方式,与以下方式实现的功能相同:
[r.split() for r in res]

现在的问题是,您把r.split()视为最终结果。相反,您应该将其作为进一步处理的源:
[s for r in res for s in r.split()]

这种方法似乎也相当快,可以在这里看到。 - RoadRunner
1
@RoadRunner 使用var ='sans' * 1000n = 40看起来更好: https://ideone.com/6dC8Rb。但有趣的是,Dekel的速度甚至更快。这似乎不对,所以我在本地独立地测试它们(也使用Python 3.5),我的速度更快。然后我将我的移动到最后,结果变得最快:https://ideone.com/yYXRrn。然后我将*您的*移动到最后,*它*几乎成为最快的:https://ideone.com/sN5Gnn。我想我必须停止在ideone上进行基准测试。似乎后来的测试从先前的测试中受益,从而提高了进程优先级或其他方面。 - Stefan Pochmann

2

如果您有一个列表

cor = [['sans'], ['s', 'ans'], ['sa', 'ns'], ['san', 's']]

如果您想将其压平,可以使用以下操作:
flat = [x for y in cor for x in y]

输出结果将会是:
['sans', 's', 'ans', 'sa', 'ns', 'san', 's']

您可以直接使用res变量来实现这一点:
cor = [x for y in [res[i].split() for i in range (len(res))] for x in y]

最好一开始就不要构建那个“cor”。 - Stefan Pochmann
@StefanPochmann,你是对的,我也添加了一个示例。 - Dekel
不,那不是我的意思。你仍然在以完全相同的错误方式构建列表。 - Stefan Pochmann

1
你可以始终使用 map()res 中的每个字符串拆分:
list(map(str.split, res))

Which gives:

[['sans'], ['s', 'ans'], ['sa', 'ns'], ['san', 's']]

然后您可以使用itertools.chain.from_iterable来展开列表:

list(chain.from_iterable(map(str.split, res)))

输出什么内容:

['sans', 's', 'ans', 'sa', 'ns', 'san', 's']

0
你可以在一行代码中做到这一点,而无需导入任何模块:
var ='sans'

final=[]
list(map(lambda x:list(map(lambda y:final.append(y),x)),[(var[i:]+' '+var[:i]).split() for i in range(0,len(var))]))
print(final)

输出:

['sans', 'ans', 's', 'ns', 'sa', 's', 'san']

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接