如何使用列表推导来处理嵌套列表?

2024-11-29 08:41:00
admin
原创
9
摘要:问题描述:我有这个嵌套列表:l = [['40', '20', '10', '30'], ['20', '20', '20', '20', '20', '30', '20'], ['30', '20', '30', '50', '10', '30', '20', '20', '20'], ['100', '1...

问题描述:

我有这个嵌套列表:

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']]

我想将 中的每个元素转换lfloat。我有以下代码:

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

我怎样才能用嵌套列表理解来解决问题?


另请参阅:如何从列表推导而不是嵌套列表获得平面结果?


解决方案 1:

使用嵌套列表推导式可以这样做:

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

这将为您提供一个列表列表,与您开始时的列表类似,只是使用浮点数而不是字符串。

如果你想要一个平面列表,那么你可以使用

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

注意循环顺序 -for x in l在这个循环中是第一位的。

解决方案 2:

以下是将嵌套 for 循环转换为嵌套列表推导的方法:

#   l a b c d e f
#   ↓ ↓ ↓ ↓ ↓ ↓ ↓
l = [ [ [ [ [ [ 1 ] ] ] ] ] ]

new_list = []
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.append(float(f))
                        


new_list = [
    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
]

# new_list => [1.0]

对于您的情况,如果您想要一个平面列表,它将是这样的。

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

另一个有趣的例子是混合了 if 条件的:

school_data = [
    {
        "students": [
            {"name": "John", "age": 18, "friends": ["Alice", "Bob"]},
            {"name": "Alice", "age": 19, "friends": ["John", "Bob"]},
        ],
        "teacher": "Mr. Smith",
    },
    {
        "students": [
            {"name": "Sponge", "age": 20, "friends": ["Bob"]},
        ],
        "teacher": "Mr. tom",
    },
]

result = []

for class_dict in school_data:
    for student_dict in class_dict["students"]:
        if student_dict["name"] == "John" and student_dict["age"] == 18:
            for friend_name in student_dict["friends"]:
                if friend_name.startswith("A"):
                    result.append(friend_name)

这是listcomp版本

result = [
    friend_name
    for class_dict in school_data
        if class_dict["teacher"] == "Mr. Smith"
            for student_dict in class_dict["students"]
                if student_dict["name"] == "John" and student_dict["age"] == 18
                    for friend_name in student_dict["friends"]
                        if friend_name.startswith("A")
]
# result => ['Alice']

解决方案 3:

不确定您想要的输出是什么,但是如果您使用列表推导,则顺序遵循嵌套循环的顺序,而嵌套循环的顺序是反向的。所以我得到了我认为您想要的:

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

原则是:使用与嵌套 for 循环相同的顺序来写出它。

解决方案 4:

>>> 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]

解决方案 5:

我想分享列表推导的实际工作方式,尤其是嵌套列表推导:

new_list= [float(x) for x in l]

实际上与以下相同:

new_list=[]
for x in l:
    new_list.append(float(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]]

解决方案 6:

我有一个类似的问题需要解决,所以我遇到了这个问题。我对 Andrew Clark 和 narayan 的答案进行了性能比较,我想分享一下。

两个答案之间的主要区别在于它们如何迭代内部列表。其中一个使用内置map,而另一个使用列表理解。如果不需要使用 lambdas ,则 Map 函数比其等效列表理解具有轻微的性能优势。因此,在这个问题的背景下,它的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

在此处输入图片描述

在下一组测试中,我想将每个列表的元素数量增加到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

在此处输入图片描述

让我们勇敢地迈出一步,将列表中元素的数量修改为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

在此处输入图片描述

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

但是我个人觉得列表推导比 更易读、更符合语法map。它是 Python 中事实上的标准。通常人们(尤其是初学者)使用列表推导比 更熟练、更自如map

解决方案 7:

如果你不喜欢嵌套列表推导,你也可以使用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]]

解决方案 8:

无需使用 for 循环即可解决此问题。单行代码就足够了。使用嵌套 Map 和 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]]

解决方案 9:

是的,你可以用这样的代码来实现:

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

解决方案 10:

如果需要扁平列表:

[y for x in l for y in x]

如果需要嵌套列表(列表中的列表):

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

解决方案 11:

我认为实现此目的的最佳方法是使用 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]

解决方案 12:

    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 ]

解决方案 13:

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

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

解决方案 14:

from py_linq import Enumerable

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']]

# non-flattened
Enumerable(l).select(lambda ls: Enumerable(ls).select(lambda x: float(x)))

# flattened
Enumerable(l).select_many(lambda ls: Enumerable(ls).select(lambda x: float(x)))
相关推荐
  为什么项目管理通常仍然耗时且低效?您是否还在反复更新电子表格、淹没在便利贴中并参加每周更新会议?这确实是耗费时间和精力。借助软件工具的帮助,您可以一目了然地全面了解您的项目。如今,国内外有足够多优秀的项目管理软件可以帮助您掌控每个项目。什么是项目管理软件?项目管理软件是广泛行业用于项目规划、资源分配和调度的软件。它使项...
项目管理软件   657  
  如何借鉴华为IPD体系优化企业研发?在当今竞争激烈的市场环境中,企业要想保持技术领先和产品竞争力,必须拥有一套高效且严谨的研发管理体系。华为作为全球领先的ICT解决方案提供商,其集成产品开发(IPD, Integrated Product Development)体系与质量管理体系(如ISO 9000系列)的融合实践,...
IPD项目管理   15  
  IPD流程图的7种经典绘制方法详解在产品开发领域,集成产品开发(Integrated Product Development,简称IPD)流程被广泛应用,以提高产品开发的效率和质量。IPD流程图作为这一流程的可视化工具,其绘制方法至关重要。本文将详细介绍七种经典的IPD流程图绘制方法,帮助项目管理人员和团队更好地理解和...
IPD研发管理体系   18  
  IPD流程:企业创新管理的核心引擎在当今快速变化的市场环境中,企业要想持续保持竞争力,就必须不断进行创新。而IPD(Integrated Product Development,集成产品开发)流程作为一种先进的产品开发管理模式,正逐渐成为众多企业提升创新能力、加速产品上市速度、降低开发成本的重要选择。本文将深入探讨IP...
IPD管理   18  
  IPD流程与传统产品开发流程的概述在产品开发领域,企业不断寻求高效、系统的管理方法以确保产品能够顺利从概念转化为市场成功的产品。集成产品开发(Integrated Product Development,简称IPD)流程与传统产品开发流程是两种截然不同的管理理念和方法。传统产品开发流程往往以职能部门为核心,各部门按顺序...
IPD流程中PDCP是什么意思   16  
热门文章
项目管理软件有哪些?
云禅道AD
禅道项目管理软件

云端的项目管理软件

尊享禅道项目软件收费版功能

无需维护,随时随地协同办公

内置subversion和git源码管理

每天备份,随时转为私有部署

免费试用