我正在为我的作业制作心脏游戏,但我不知道如何将每个元素列入列表列表中:
>>>Cards = [[["QS","5H","AS"],["2H","8H"],["7C"]],[["9H","5C],["JH"]],[["7D"]]]
我想到的是:
for values in cards:
for value in values:
但我想我的元素有2个列表。如何计算卡中有3个和1个列表的那个?
答案 0 :(得分:15)
像这样:
>>> Cards = [[["QS","5H","AS"],["2H","8H"],["7C"]],[["9H","5C"],["JH"]],["7D"]]
>>> from compiler.ast import flatten
>>> flatten(Cards)
['QS', '5H', 'AS', '2H', '8H', '7C', '9H', '5C', 'JH', '7D']
正如nacholibre指出的那样,compiler
包已被弃用。这是flatten
:
def flatten(seq):
l = []
for elt in seq:
t = type(elt)
if t is tuple or t is list:
for elt2 in flatten(elt):
l.append(elt2)
else:
l.append(elt)
return l
答案 1 :(得分:5)
稍微晦涩的oneliner:
>>> [a for c in Cards for b in c for a in b]
['QS', '5H', 'AS', '2H', '8H', '7C', '9H', '5C', 'JH', '7', 'D']
您可能想要给出a,b和c更具描述性的名称。
答案 2 :(得分:4)
如果您的卡片以笨重的方式嵌套:
>>> Cards = [[["QS","5H","AS"],["2H","8H"],["7C"]],[["9H","5C"],["JH"]],["7D"]]
>>> def getCards(cardList,myCards=[]): #change this to myCards, and pass in a list to mutate this is just for demo
if isinstance(cardList,list):
for subList in cardList:
getCards(subList)
else:
myCards.append(cardList)
return myCards
>>> getCards(Cards)
['QS', '5H', 'AS', '2H', '8H', '7C', '9H', '5C', 'JH', '7D']
将递归遍历列表并查找所有元素。这些是我运行的时间比较所选flattern
方法的性能:
>>> print(timeit.timeit(r'getCards([[["QS","5H","AS"],["2H","8H"],["7C"]],[["9H","5C"],["JH"]],["7D"]],[])',setup="from clas import getCards"))
5.24880099297
>>> timeit.timeit(r'flatten([[["QS","5H","AS"],["2H","8H"],["7C"]],[["9H","5C"],["JH"]],["7D"]])',setup="from compiler.ast import flatten")
7.010887145996094
答案 3 :(得分:2)
您的列表是一个不完整的嵌套列表,因此您可以先将其设为矩形,using the procedure explained here,然后展平生成的numpy.ndarray
。
如果最后一个元素['7D']是[['7D']],则下面的“ifs”也是不必要的(那么其他答案也可以)。
import numpy as np
collector = np.zeros((3,3,3),dtype='|S20')
for (i,j,k), v in np.ndenumerate( collector ):
try:
if not isinstance(cards[i], str):
if not isinstance(cards[i][j], str):
collector[i,j,k] = cards[i][j][k]
else:
collector[i,j,0] = cards[i][j]
else:
collector[i,0,0] = cards[i]
except IndexError:
collector[i,j,k] = ''
print collector[collector<>''].flatten()
答案 4 :(得分:2)
使用生成器,可以编写更加可读的flatten
实现:
def flatten(l):
if isinstance(l, list):
for e1 in l:
for e2 in flatten(e1):
yield e2
else:
yield l
或者,如果您使用的是Python 3.3,它添加了yield from
语法:
def flatten(l):
if isinstance(l, list):
for e in l:
yield from flatten(e)
else:
yield l
结果:
>>> list(flatten([[["QS","5H","AS"],["2H","8H"],["7C"]],[["9H","5C"],["JH"]],[["7D"]]]))
['QS', '5H', 'AS', '2H', '8H', '7C', '9H', '5C', 'JH', '7D']
答案 5 :(得分:2)
使用2个嵌套itertools.chain来展平列表:
In [32]: Cards
Out[32]: [[['QS', '5H', 'AS'], ['2H', '8H'], ['7C']], [['9H', '5C'], ['JH']], ['7D']]
In [33]: from itertools import chain
In [34]: [k for k in chain.from_iterable([i for i in chain.from_iterable(Cards)])]
Out[34]: ['QS', '5H', 'AS', '2H', '8H', '7C', '9H', '5C', 'JH', '7', 'D']
答案 6 :(得分:2)
此解决方案对于任何类型的嵌套列表或元组都非常健壮(要添加其他可迭代类型,只需在下面的代码中添加更多or isinstance(...)
。
它只是递归地调用一个展开自身的函数:
def unfold(lst):
output = []
def _unfold(i):
if isinstance(i, list) or isinstance(i, tuple):
[_unfold(j) for j in i]
else:
output.append(i)
_unfold(lst)
return output
print unfold(cards)
#['QS', '5H', 'AS', '2H', '8H', '7C', '9H', '5C', 'JH', '7D']
答案 7 :(得分:1)
使用Rosetta Code中的Flatten a list,您可以这样做:
>>> def flatten(lst):
return sum( ([x] if not isinstance(x, list) else flatten(x)
for x in lst), [] )
>>> Cards = [[["QS","5H","AS"],["2H","8H"],["7C"]],[["9H","5C"],["JH"]],["7D"]]
>>> flatten(Cards)
['QS', '5H', 'AS', '2H', '8H', '7C', '9H', '5C', 'JH', '7D']
>>>
该解决方案仅展平嵌套列表 - 而不是元组或字符串。
答案 8 :(得分:1)
from itertools import chain, imap
l= [[["QS","5H","AS"],["2H","8H"],["7C"]],[["9H","5C"],["JH"]],[["7D"]]]
k = list(chain.from_iterable(imap(list, l)))
m = list(chain.from_iterable(imap(list, k)))
print m
输出:['QS','5H','AS','2H','8H','7C','9H','5C','JH','7D']
Itertools很棒!