首页 文章

在嵌套列表上列出理解?

提问于
浏览 95
167

我有这个嵌套列表:

l = [['40', '20', '10', '30'], ['20', '20', '20', '20', '20', '30', '20'], ['30', '20', '30', '50', '10', '30', '20', '20', '20'], ['100', '100'], ['100', '100', '100', '100', '100'], ['100', '100', '100', '100']]

现在,我想要做的是将列表中的每个元素转换为float . 我的解决方案是:

newList = []
for x in l:
  for y in x:
    newList.append(float(y))

但这可以使用嵌套列表理解来完成,对吗?

我所做的是:

[float(y) for y in x for x in l]

但结果是一堆100的总和2400 .

任何解决方案,将非常感谢解释 . 谢谢!

12 回答

  • 248

    是的,您可以使用以下代码执行此操作:

    l = [[float(y) for y in x] for x in l]
    
  • 92

    在我看来,最好的方法是使用python的 itertools 包 .

    >>>import itertools
    >>>l1 = [1,2,3]
    >>>l2 = [10,20,30]
    >>>[l*2 for l in itertools.chain(*[l1,l2])]
    [2, 4, 6, 20, 40, 60]
    
  • 44

    由于我在这里很晚,但我想分享实际列表理解是如何工作的,尤其是嵌套列表理解:

    New_list= [[float(y) for x in l]
    

    实际上是这样的:

    New_list=[]
    for x in l:
        New_list.append(x)
    

    现在嵌套列表理解:

    [[float(y) for y in x] for x in l]
    

    和...一样

    new_list=[]
    for x in l:
        sub_list=[]
        for y in x:
            sub_list.append(float(y))
    
        new_list.append(sub_list)
    
    print(new_list)
    

    输出:

    [[40.0, 20.0, 10.0, 30.0], [20.0, 20.0, 20.0, 20.0, 20.0, 30.0, 20.0], [30.0, 20.0, 30.0, 50.0, 10.0, 30.0, 20.0, 20.0, 20.0], [100.0, 100.0], [100.0, 100.0, 100.0, 100.0, 100.0], [100.0, 100.0, 100.0, 100.0]]
    
  • 29

    不确定你想要的输出是什么,但是如果你正在使用列表理解,那么顺序遵循嵌套循环的顺序,你已经倒退了 . 所以我得到了我认为你想要的东西:

    [float(y) for x in l for y in x]
    

    原则是:使用您在编写嵌套for循环时使用的相同顺序 .

  • 4

    是的,您可以执行以下操作 .

    [[float(y) for y in x] for x in l]
    
  • 4
    deck = [] 
        for rank in ranks:
            for suit in suits:
                deck.append(('%s%s')%(rank, suit))
    

    这可以使用列表理解来实现:

    [deck.append((rank,suit)) for suit in suits for rank in ranks ]
    
  • 3

    这个问题可以在不使用for循环的情况下解决 . 单行代码就足够了 . 使用带有lambda函数的嵌套映射也适用于此处 .

    l = [['40', '20', '10', '30'], ['20', '20', '20', '20', '20', '30', '20'], ['30', '20', '30', '50', '10', '30', '20', '20', '20'], ['100', '100'], ['100', '100', '100', '100', '100'], ['100', '100', '100', '100']]
    
    map(lambda x:map(lambda y:float(y),x),l)
    

    输出清单如下:

    [[40.0, 20.0, 10.0, 30.0], [20.0, 20.0, 20.0, 20.0, 20.0, 30.0, 20.0], [30.0, 20.0, 30.0, 50.0, 10.0, 30.0, 20.0, 20.0, 20.0], [100.0, 100.0], [100.0, 100.0, 100.0, 100.0, 100.0], [100.0, 100.0, 100.0, 100.0]]
    
  • 2
    >>> l = [['40', '20', '10', '30'], ['20', '20', '20', '20', '20', '30', '20'], ['30', '20', '30', '50', '10', '30', '20', '20', '20'], ['100', '100'], ['100', '100', '100', '100', '100'], ['100', '100', '100', '100']]
    >>> new_list = [float(x) for xs in l for x in xs]
    >>> new_list
    [40.0, 20.0, 10.0, 30.0, 20.0, 20.0, 20.0, 20.0, 20.0, 30.0, 20.0, 30.0, 20.0, 30.0, 50.0, 10.0, 30.0, 20.0, 20.0, 20.0, 100.0, 100.0, 100.0, 100.0, 100.0, 100.0, 100.0, 100.0, 100.0, 100.0, 100.0]
    
  • 2

    如果你不喜欢嵌套列表推导,你也可以使用map函数,

    >>> from pprint import pprint
    
    >>> l = l = [['40', '20', '10', '30'], ['20', '20', '20', '20', '20', '30', '20'], ['30', '20', '30', '50', '10', '30', '20', '20', '20'], ['100', '100'], ['100', '100', '100', '100', '100'], ['100', '100', '100', '100']] 
    
    >>> pprint(l)
    [['40', '20', '10', '30'],
    ['20', '20', '20', '20', '20', '30', '20'],
    ['30', '20', '30', '50', '10', '30', '20', '20', '20'],
    ['100', '100'],
    ['100', '100', '100', '100', '100'],
    ['100', '100', '100', '100']]
    
    >>> float_l = [map(float, nested_list) for nested_list in l]
    
    >>> pprint(float_l)
    [[40.0, 20.0, 10.0, 30.0],
    [20.0, 20.0, 20.0, 20.0, 20.0, 30.0, 20.0],
    [30.0, 20.0, 30.0, 50.0, 10.0, 30.0, 20.0, 20.0, 20.0],
    [100.0, 100.0],
    [100.0, 100.0, 100.0, 100.0, 100.0],
    [100.0, 100.0, 100.0, 100.0]]
    
  • 0

    以下是使用嵌套列表理解的方法:

    [[float(y) for y in x] for x in l]
    

    这将为您提供一个列表列表,类似于您开始使用的列表,除了浮点数而不是字符串 . 如果你想要一个平面列表,那么你将使用 [float(y) for x in l for y in x] .

  • 0

    我有一个类似的问题需要解决,所以我遇到了这个问题 . 我对安德鲁·克拉克和纳拉扬的答案进行了性能比较,我想分享一下 .

    两个答案之间的主要区别在于它们如何迭代内部列表 . 其中一个使用内置map,而另一个使用列表理解 . Map function has slight performance advantage to its equivalent list comprehension if it doesn't require the use lambdas . 因此,在这个问题的上下文中, map 应该比列表理解稍微好一些 .

    让我们做一个性能基准测试,看看它是否真的如此 . 我使用python版本3.5.0来执行所有这些测试 . 在第一组测试中,我希望每个列表中的元素保持为10,并且列表的数量从10-100,000不等

    >>> python -m timeit "[list(map(float,k)) for k in [list(range(0,10))]*10]"
    >>> 100000 loops, best of 3: 15.2 usec per loop   
    >>> python -m timeit "[[float(y) for y in x] for x in [list(range(0,10))]*10]"
    >>> 10000 loops, best of 3: 19.6 usec per loop 
    
    >>> python -m timeit "[list(map(float,k)) for k in [list(range(0,10))]*100]"
    >>> 100000 loops, best of 3: 15.2 usec per loop
    >>> python -m timeit "[[float(y) for y in x] for x in [list(range(0,10))]*100]"
    >>> 10000 loops, best of 3: 19.6 usec per loop 
    
    >>> python -m timeit "[list(map(float,k)) for k in [list(range(0,10))]*1000]"
    >>> 1000 loops, best of 3: 1.43 msec per loop   
    >>> python -m timeit "[[float(y) for y in x] for x in [list(range(0,10))]*1000]"
    >>> 100 loops, best of 3: 1.91 msec per loop
    
    >>> python -m timeit "[list(map(float,k)) for k in [list(range(0,10))]*10000]"
    >>> 100 loops, best of 3: 13.6 msec per loop   
    >>> python -m timeit "[[float(y) for y in x] for x in [list(range(0,10))]*10000]"
    >>> 10 loops, best of 3: 19.1 msec per loop
    
    >>> python -m timeit "[list(map(float,k)) for k in [list(range(0,10))]*100000]"
    >>> 10 loops, best of 3: 164 msec per loop
    >>> python -m timeit "[[float(y) for y in x] for x in [list(range(0,10))]*100000]"
    >>> 10 loops, best of 3: 216 msec per loop
    

    enter image description here

    在下一组测试中,我想将每个列表的元素数量增加到100 .

    >>> python -m timeit "[list(map(float,k)) for k in [list(range(0,100))]*10]"
    >>> 10000 loops, best of 3: 110 usec per loop
    >>> python -m timeit "[[float(y) for y in x] for x in [list(range(0,100))]*10]"
    >>> 10000 loops, best of 3: 151 usec per loop
    
    >>> python -m timeit "[list(map(float,k)) for k in [list(range(0,100))]*100]"
    >>> 1000 loops, best of 3: 1.11 msec per loop
    >>> python -m timeit "[[float(y) for y in x] for x in [list(range(0,100))]*100]"
    >>> 1000 loops, best of 3: 1.5 msec per loop
    
    >>> python -m timeit "[list(map(float,k)) for k in [list(range(0,100))]*1000]"
    >>> 100 loops, best of 3: 11.2 msec per loop
    >>> python -m timeit "[[float(y) for y in x] for x in [list(range(0,100))]*1000]"
    >>> 100 loops, best of 3: 16.7 msec per loop
    
    >>> python -m timeit "[list(map(float,k)) for k in [list(range(0,100))]*10000]"
    >>> 10 loops, best of 3: 134 msec per loop
    >>> python -m timeit "[[float(y) for y in x] for x in [list(range(0,100))]*10000]"
    >>> 10 loops, best of 3: 171 msec per loop
    
    >>> python -m timeit "[list(map(float,k)) for k in [list(range(0,100))]*100000]"
    >>> 10 loops, best of 3: 1.32 sec per loop
    >>> python -m timeit "[[float(y) for y in x] for x in [list(range(0,100))]*100000]"
    >>> 10 loops, best of 3: 1.7 sec per loop
    

    enter image description here

    让我们采取勇敢的步骤,并将列表中的元素数量修改为1000

    >>> python -m timeit "[list(map(float,k)) for k in [list(range(0,1000))]*10]"
    >>> 1000 loops, best of 3: 800 usec per loop
    >>> python -m timeit "[[float(y) for y in x] for x in [list(range(0,1000))]*10]"
    >>> 1000 loops, best of 3: 1.16 msec per loop
    
    >>> python -m timeit "[list(map(float,k)) for k in [list(range(0,1000))]*100]"
    >>> 100 loops, best of 3: 8.26 msec per loop
    >>> python -m timeit "[[float(y) for y in x] for x in [list(range(0,1000))]*100]"
    >>> 100 loops, best of 3: 11.7 msec per loop
    
    >>> python -m timeit "[list(map(float,k)) for k in [list(range(0,1000))]*1000]"
    >>> 10 loops, best of 3: 83.8 msec per loop
    >>> python -m timeit "[[float(y) for y in x] for x in [list(range(0,1000))]*1000]"
    >>> 10 loops, best of 3: 118 msec per loop
    
    >>> python -m timeit "[list(map(float,k)) for k in [list(range(0,1000))]*10000]"
    >>> 10 loops, best of 3: 868 msec per loop
    >>> python -m timeit "[[float(y) for y in x] for x in [list(range(0,1000))]*10000]"
    >>> 10 loops, best of 3: 1.23 sec per loop
    
    >>> python -m timeit "[list(map(float,k)) for k in [list(range(0,1000))]*100000]"
    >>> 10 loops, best of 3: 9.2 sec per loop
    >>> python -m timeit "[[float(y) for y in x] for x in [list(range(0,1000))]*100000]"
    >>> 10 loops, best of 3: 12.7 sec per loop
    

    enter image description here

    从这些测试中我们可以得出结论,在这种情况下, map 具有优于列表理解的性能优势 . 如果您尝试强制转换为 intstr ,这也适用 . 对于每个列表中元素较少的少量列表,差异可以忽略不计 . 对于每个列表包含更多元素的较大列表,可能希望使用 map 而不是列表推导,但这完全取决于应用程序需求 .

    但是我个人觉得列表理解比 map 更具可读性和惯用性 . 它是python中事实上的标准 . 通常人们使用列表理解比 map 更熟练和舒适(特别是初学者) .

  • -2

    以下是如何将嵌套for循环转换为嵌套列表理解:

    enter image description here

    以下是嵌套列表理解的工作原理:

    l a b c d e f
                ↓ ↓ ↓ ↓ ↓ ↓ ↓
    In [1]: l = [ [ [ [ [ [ 1 ] ] ] ] ] ]
    In [2]: for a in l:
       ...:     for b in a:
       ...:         for c in b:
       ...:             for d in c:
       ...:                 for e in d:
       ...:                     for f in e:
       ...:                         print(float(f))
       ...:                         
    1.0
    
    In [3]: [float(f)
             for a in l
       ...:     for b in a
       ...:         for c in b
       ...:             for d in c
       ...:                 for e in d
       ...:                     for f in e]
    Out[3]: [1.0]
    
    #Which can be written in single line as
    In [4]: [float(f) for a in l for b in a for c in b for d in c for e in d for f in e]
    Out[4]: [1.0]
    

相关问题