将列表合并成一个列表

19
我正在编写一个小脚本来帮助记忆日语假名。如何将以下列表合并为一个列表?我尝试了以下方法。
a = ["a",   "i",   "u",   "e",   "o"]
k = ["ka",  "ki",  "ku",  "ke",  "ko"]
g = ["ga",  "gi",  "gu",  "ge",  "go"]
s = ["sa",  "shi", "su",  "se",  "so"]
z = ["za",  "ji",  "zu",  "ze",  "zo"]
t = ["ta",  "chi", "tsu", "te",  "to"]
d = ["da",         "du",  "de",  "do"]
n = ["na",  "ni",  "nu",  "ne",  "no"]
h = ["ha",  "hi",  "hu",  "he",  "ho"]
b = ["ba",  "bi",  "bu",  "be",  "bo"]
p = ["pa",  "pi",  "pu",  "pe",  "po"]
m = ["ma",  "mi",  "mu",  "me",  "mo"]
y = ["ya",         "yu",         "yo"]
n = ["n"]

kana = [a, k, g, s, z, t, d, n, h, b, p, m, y, n]

print kana

谢谢,我确实搜索过了,但没有找到有用的东西。这些答案都很有帮助,谢谢大家! :) - abkai
8个回答

22

一种方法:

kana = a + k + g + s + z + t + d + n + h + b + p + m + y + n

18
问题实际上在问如何展开该列表,答案在这里: join list of lists in python
您可以通过执行以下操作打印出所有内容:
import itertools
print list(itertools.chain(*kana))

3
或者chain.from_iterable(kana) - John La Rooy
2
在我看来,itertools解决方案绝对适合那些习惯于使用itertools并在其他代码中使用该模块的人。否则,它比使用基本类型的方法更不易理解。而且速度较慢--请参见我的答案中的timeit。 - pepr

9

我支持使用显式的for循环.extend()方法。

>>> import this
The Zen of Python, by Tim Peters

Beautiful is better than ugly.
Explicit is better than implicit.
...
Readability counts.
...
In the face of ambiguity, refuse the temptation to guess.
...

在测量时,普通的for循环比列表推导式中的副作用更快。

import itertools
import timeit

def flattenListOfLists(lst):
    result = []
    for sublist in lst:
        result.extend(sublist)
    return result

def flattenListOfLists2(lst):
    result = []
    [result.extend(sublist) for sublist in lst]  # uggly side effect ;)
    return result

def flattenIterTools(lst):
    return list(itertools.chain(*lst))


a = ["a",   "i",   "u",   "e",   "o"]
k = ["ka",  "ki",  "ku",  "ke",  "ko"]
g = ["ga",  "gi",  "gu",  "ge",  "go"]
s = ["sa",  "shi", "su",  "se",  "so"]
z = ["za",  "ji",  "zu",  "ze",  "zo"]
t = ["ta",  "chi", "tsu", "te",  "to"]
d = ["da",         "du",  "de",  "do"]
n = ["na",  "ni",  "nu",  "ne",  "no"]
h = ["ha",  "hi",  "hu",  "he",  "ho"]
b = ["ba",  "bi",  "bu",  "be",  "bo"]
p = ["pa",  "pi",  "pu",  "pe",  "po"]
m = ["ma",  "mi",  "mu",  "me",  "mo"]
y = ["ya",         "yu",         "yo"]
n = ["n"]

kana = [a, k, g, s, z, t, d, n, h, b, p, m, y, n]

t = timeit.timeit('lst = flattenListOfLists(kana)', 'from __main__ import kana, flattenListOfLists', number=100000)
print 'for loop:', t

t = timeit.timeit('lst = flattenListOfLists2(kana)', 'from __main__ import kana, flattenListOfLists2', number=100000)
print 'list comprehension side effect:', t

t = timeit.timeit('lst = flattenIterTools(kana)', 'from __main__ import kana, flattenIterTools\nimport itertools', number=100000)
print 'itertools:', t

它会在我的控制台上打印输出:

for loop: 0.389831948464
list comprehension side effect: 0.468136159616
itertools: 0.620626692887

总之,时间就是重复100,000次同样的事情。易读性至关重要,这是我的论点。


5
kana = sum([a, k, g, s, z, t, d, n, h, b, p, m, y, n], [])

2
使用sum()函数对列表进行求和会导致二次时间复杂度。每次添加另一个列表时,它都会创建一个全新的列表。 - John La Rooy
'+' 运算符也不是这种情况吗? - spinlok
1
@spinlok 是的,对于这个问题,+sum 都是同样糟糕的选择。最好的方法是使用 itertools.chain,正如 @JackKelly 和 @gnibbler 所提到的,它不会构建任何中间列表。 - lvc

2

需要注意的一个非常重要的事实是,扁平化列表与原始的列表共享相同的对象。对于不可变字符串而言,这不是问题。但如果对象是可变的,那么在一个结构中更改它们会更改通过第二个结构可观察到的元素值。

总之,我们需要了解Python内部的一些知识。有时候我们想要复制原始子列表,像这样:

...
result = []
for sublist in lst:
    result.extend(sublist[:])     # notice the [:] here
...

1
以下是一个列表推导式,其中so_on只是在示例中用作快捷方式,代表您想要组合的实际剩余列表。
冗长的方法:
>>> all_list = [e for l in [a, k, so_on] for e in l]

1
kana = [a, k, g, s, z, t, d, n, h, b, p, m, y, n]
combined_list=[]
for x in kana:
    combined_list.extend(x) 
print(combined_list)

['a', 'i', 'u', 'e', 'o', 'ka', 'ki', 'ku', 'ke', 'ko', 'ga', 'gi', 'gu', 'ge', 'go', 'sa', 'shi', 'su', 'se', 'so', 'za', 'ji', 'zu', 'ze', 'zo', 'ta', 'chi', 'tsu', 'te', 'to', 'da', 'du', 'de', 'do', 'n', 'ha', 'hi', 'hu', 'he', 'ho', 'ba', 'bi', 'bu', 'be', 'bo', 'pa', 'pi', 'pu', 'pe', 'po', 'ma', 'mi', 'mu', 'me', 'mo', 'ya', 'yu', 'yo', 'n']

1
使用列表推导式来产生副作用通常被认为是不符合Python风格的。 - John La Rooy
@gnibbler 你说得对,但我在这里使用它只是因为列表推导式很快。 - Ashwini Chaudhary
1
真的吗?你计时了LC和for循环的时间吗? - John La Rooy
2
在我的电脑上,for x in kana:combined_list.extend(x) 比 LC 快20%。 - John La Rooy
@Ashwini Chaudhary:“面对模棱两可的情况,拒绝猜测的诱惑。” ;) 我同意gnibbler的观点,但我认为这是一个有价值的例子可以从中学习。我不会点赞,但我也不会点踩。副作用应该尽可能避免(不仅在Python中)。 - pepr
@gnibbler 谢谢,我真的不知道当作副作用使用的LC比for循环慢,解决方案已编辑。 - Ashwini Chaudhary

1

使用lambda的另一种方式

kana = [a, k, g, s, z, t, d, n, h, b, p, m, y, n]

reduce(lambda x,y: x+y,kana)

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