[英]How to get every element in a list of list of lists?
I'm making a heart game for my assignment but I don't know how to get every element in a list of list: 我正在为我的任务做心脏游戏,但我不知道如何获取列表中的每个元素:
>>>Cards = [[["QS","5H","AS"],["2H","8H"],["7C"]],[["9H","5C],["JH"]],[["7D"]]]
and what comes to my mind is : 我想到的是:
for values in cards:
for value in values:
But I think I just got element that has 2 list. 但是我想我只有2个元素。 How to calculate the one that has 3 and 1 list in the cards?
如何计算卡片中有3个和1个列表的那个?
Like this: 像这样:
>>> 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']
As, nacholibre pointed out, the compiler
package is deprecated. 正如nacholibre指出的那样,不建议使用
compiler
软件包。 This is the source of flatten
: 这是
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
Slightly obscure 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']
You might want to give a, b and c more descriptive names. 您可能想给a,b和c更多描述性的名称。
If your cards are nested in a unwieldy way: 如果您的卡片以笨拙的方式嵌套:
>>> 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']
Will recursivly go through the list and find all the elements. 将递归地浏览列表并找到所有元素。 These are some timeings I've run comparing performance of the selected
flattern
method to mine: 以下是一些我比较选定的
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
Your list is an incomplete nested list, so you can first make it rectangular, using the procedure explained here , for example, and then flatten the resulting numpy.ndarray
. 您的列表是一个不完整的嵌套列表,因此您可以首先使用此处说明的过程将其
numpy.ndarray
矩形,然后再将生成的numpy.ndarray
展平。
The "ifs" below wouldn't be necessary as well if the last element ['7D'] was [['7D']] (then the other answers would also work). 如果最后一个元素['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()
Using generators, it's possible to write a much more readable implementation of flatten
: 使用生成器,可以编写更加易读的
flatten
实现:
def flatten(l):
if isinstance(l, list):
for e1 in l:
for e2 in flatten(e1):
yield e2
else:
yield l
Or, if you're using Python 3.3, which added the yield from
syntax: 或者,如果您使用的是Python 3.3,则可以
yield from
语法中添加yield from
:
def flatten(l):
if isinstance(l, list):
for e in l:
yield from flatten(e)
else:
yield l
Result: 结果:
>>> list(flatten([[["QS","5H","AS"],["2H","8H"],["7C"]],[["9H","5C"],["JH"]],[["7D"]]]))
['QS', '5H', 'AS', '2H', '8H', '7C', '9H', '5C', 'JH', '7D']
Use 2 nested itertools.chain to flatten the list: 使用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']
This solution is very robust for any kind of nested lists or tuples (to add other iterable types just add more or isinstance(...)
in the code below. 该解决方案对于任何类型的嵌套列表或元组都非常健壮(要添加其他可迭代类型,只需在下面的代码中添加更多
or isinstance(...)
。
It just calls recursively a function that unfolds itself: 它只是递归地调用一个自动展开的函数:
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']
Using Flatten a list from Rosetta Code you could do: 使用扁平化 Rosetta Code中的列表 ,您可以执行以下操作:
>>> 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']
>>>
The solution only flattens nested lists - not tuples or strings. 该解决方案只展平嵌套列表,而不展平元组或字符串。
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
output: ['QS', '5H', 'AS', '2H', '8H', '7C', '9H', '5C', 'JH', '7D'] 输出:['QS','5H','AS','2H','8H','7C','9H','5C','JH','7D']
Itertools is amazing! Itertools很棒!
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.