简体   繁体   English

如何获取列表列表中的每个元素?

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM