GVKun编程网logo

在Python中,使用列表推导或for-each循环会更好吗?(列表for循环 python)

31

对于想了解在Python中,使用列表推导或for-each循环会更好吗?的读者,本文将提供新的信息,我们将详细介绍列表for循环python,并且为您提供关于python–仅使用列表推导构建列表,没有

对于想了解在Python中,使用列表推导或for-each循环会更好吗?的读者,本文将提供新的信息,我们将详细介绍列表for循环 python,并且为您提供关于python – 仅使用列表推导构建列表,没有功能、python – 如何使用两个’for’来枚举列表推导?、Python 中列表推导(list comprehension)相对于循环有什么优势?性能会更高吗?、Python 全栈开发:python的推导式(列表推导式、字典推导式、集合推导式)的有价值信息。

本文目录一览:

在Python中,使用列表推导或for-each循环会更好吗?(列表for循环 python)

在Python中,使用列表推导或for-each循环会更好吗?(列表for循环 python)

以下哪个更适合使用,为什么?

方法1:

for k, v in os.environ.items():       print "%s=%s" % (k, v)

方法2:

print "\n".join(["%s=%s" % (k, v)    for k,v in os.environ.items()])

我倾向于通向第一个更容易理解,但这可能只是因为我是Python的新手,并且列表理解对我来说仍然有些陌生。第二种方法是否更像Pythonic?我假设没有性能差异,但是我可能是错的。这两种技术的优缺点是什么?

(从 Dive到Python的代码

答案1

小编典典

如果迭代是出于其副作用而进行的(如“打印”示例中所示),则循环更加清晰。

如果执行迭代以构建复合值,则列表推导通常更具可读性。

python – 仅使用列表推导构建列表,没有功能

python – 仅使用列表推导构建列表,没有功能

特定

userplays = { "Alice"   : { "AC/DC" : 2,"The Raconteurs" : 3,"mogwai" : 1
                          },"Bob"     : { "The XX" : 4,"Lady Gaga" : 3,"mogwai" : 1,"The Raconteurs" : 1
                          },"Charlie" : { "AC/DC" : 7,"Lady Gaga" : 7
                          }
            }

获取所有乐队的列表:

[''Lady Gaga'',''mogwai'',''AC/DC'',''The Raconteurs'',''The XX'']

我可以

list(set(flatten([ [ band 
                     for band 
                     in playcounts.keys() ] 
                   for playcounts 
                   in userplays.values() ] ) ) )

flatten是从Flatten (an irregular) list of lists开始,但是可以不使用flatten,只使用list / dict理解吗?

解决方法

另一种方法是使用dict理解(Python 2.7):

{k:v for v in userplays.values() for k in v.keys()}.keys()

生产:

[''Lady Gaga'',''The XX'']

至少在Python 3.3中,这也更快:

import timeit

userplays = { "Alice"   : { "AC/DC" : 2,"Lady Gaga" : 7
                          }
            }


def f1():
    set(b for v in userplays.values() for b in v.keys())

def f2():
    {k:v for v in userplays.values() for k in v.keys()}.keys()    

t1=timeit.Timer(f1).timeit(10000)
t2=timeit.Timer(f2).timeit(10000)
faster=abs(t1-t2) / max(t1,t2)
print("""
set:                {:.4} seconds
dict:               {:.4} seconds
faster of those is  {:.4%} faster

""".format(t1,t2,faster))

输出:

set:                0.02448 seconds
dict:               0.01988 seconds
faster of those is  18.7907% faster

编辑

仅仅为了纯粹的好奇心,我比较了在单行中可以做到的各种方式.

结果如下:

f1: set from a generator expression
f2: keys from a dict comprehension
f3: set comprehension
f4: set from a list comprehension

       rate/s      f4       f1       f2       f3 
f4    358,650    0.0%   -13.4%   -31.7%   -41.3% 
f1    414,246   15.5%     0.0%   -21.1%   -32.2% 
f2    525,230   46.4%    26.8%     0.0%   -14.1% 
f3    611,158   70.4%    47.5%    16.4%     0.0%

你可以看到集合理解是最快的,然后是字典理解.

以下是生成Perl样式基准的代码:

import timeit
import locale
locale.setlocale(locale.LC_NUMERIC,"")

userplays = { "Alice"   : { "AC/DC" : 2,"Lady Gaga" : 7
                          }
            }

def f1():
    """set from a generator expression"""
    set(b for v in userplays.values() for b in v.keys())

def f2():
    """keys from a dict comprehension"""
    {k:v for v in userplays.values() for k in v.keys()}.keys()    

def f3():
    """set comprehension"""
    {b for v in userplays.values() for b in v.keys()}

def f4():
    """set from a list comprehension"""
    set([b for v in userplays.values() for b in v.keys()])

def test_table(funcs,c):
    results={k.__name__:timeit.Timer(k).timeit(c) for k in funcs}
    fastest=sorted(results,key=results.get,reverse=True)
    table=[]
    table.append(['' '',''rate/s'']+fastest)
    for e in fastest:
        temp=[]
        temp.append(e)
        temp.append(int(round(float(c)/results[e])))
        t2=[''{:.1%}''.format((results[x]-results[e])/results[e]) for x in fastest]
        table.append(temp+t2)
    print()    
    for e in funcs:
        print(''{}: {}''.format(e.__name__,e.__doc__))
    print()            
    pprint_table(table)    

def format_num(num):
    """Format a number according to given places.
    Adds commas,etc. Will truncate floats into ints!"""

    try:
        inum = int(num)
        return locale.format("%.*f",(0,inum),True)

    except (ValueError,TypeError):
        return str(num)

def get_max_width(table,index):
    """Get the maximum width of the given column index"""
    return max([len(format_num(row[index])) for row in table])        

def pprint_table(table):
    col_paddings = []
    for i in range(len(table[0])):
        col_paddings.append(get_max_width(table,i))

    for row in table:
        # left col
        print(row[0].ljust(col_paddings[0] + 1),end='' '')
        # rest of the cols
        for i in range(1,len(row)):
            col = format_num(row[i]).rjust(col_paddings[i] + 2)
            print (col,end='' '')
        print()

test_table([f1,f2,f3,f4],100000)

python – 如何使用两个’for’来枚举列表推导?

python – 如何使用两个’for’来枚举列表推导?

我想做

ls = [myfunc(a,b,i) for a in a_list for b in b_list]

但也将i传入myfunc,这是一个从0开始的索引,并为每个新元素递增.

例如:

a_list = ''abc''
b_list = ''def''

应该导致

ls = [myfunc(''a'',''d'',0),myfunc(''a'',''e'',1),''f'',2),myfunc(''b'',3),4),...
      myfunc(''c'',8]

我知道我可以使用enumerate()来表示正常情况,即.

ls = [myfunc(a,i) for a,i in enumerate(a_list)]

但是,当有两个人时,我无法弄清楚如何干净利落地做到这一点.我以前找不到这个问题.

解决方法

您正在两个列表上创建一个 Cartesian product,因此请使用 itertools.product()而不是double for循环.这为您提供了一个可迭代的,您可以轻松地将enumerate()添加到:

from itertools import product

ls = [myfunc(a,i) for i,(a,b) in enumerate(product(a_list,b_list))]

对于无法使用product()的情况,您可以将多个循环放在生成器表达式中,然后将enumerate()添加到该表达式中.假设您需要过滤a_list的某些值:

gen = (a,b for a in a_list if some_filter(a) for b in b_list)
ls = [myfunc(a,b) in enumerate(gen)]

另一种选择是增加一个单独的柜台; itertools.count()为您提供了一个计数器对象,它使用next()生成一个新值:

from itertools import count

counter = count()
ls = [myfunc(a,next(counter)) 
      for a in a_list if some_filter(a)
      for b in b_list]

毕竟,实质上枚举(iterable,start = 0)相当于zip(itertools.count(start),iterable).

Python 中列表推导(list comprehension)相对于循环有什么优势?性能会更高吗?

Python 中列表推导(list comprehension)相对于循环有什么优势?性能会更高吗?

python中的列表推导(list comprehension)一般用于从一个列表计算出另一个列表,从功能上看是map/filter的结合体,也能通过循环实现。之前查过的一些相关的资料,有人说列表推导只是语法糖,也有说列表推导比循环和map/filter的写法效率更高(只给了一个测试结果,没有相关分析),其他有价值的资料就没有找到了...这是某次一个面试官问的问题,我想还是要搞清楚吧,所以就来知乎请教各位大神了。
python的设计哲学里,有一句“There should be one-- and preferably only one --obvious way to do it.”,那么如果列表推导和循环以及map/filter实现上没有什么区别的话,应该就不会存在了吧?当然python的哲学里还有“Beautiful is better than ugly.”,貌似也有可能只是为了好看的样子...

回复内容:

首先肯定 map 和列表推导效率确实会比循环的高,

先说列表推导,下边是我在 ipython 里的测试结果(测试环境 Python 2.7.10):

>>> long_list = range(1000)

>>> a = []

>>> %timeit for i in long_list: a.append(i+1)
10000 loops, best of 3: 100 µs per loop

>>> %timeit [i+1 for i in long_list]
10000 loops, best of 3: 43.3 µs per loop
登录后复制
效率高一点,去看 dis 模块。

Python 不喜欢 FP 的,而且 map / filter 是惰性的,list comprehension 不是。

循环比 list comprehension 更底层而难以被理解一些。比较:「把这个列表里的所有元素乘以二」和「创建一个空列表 B,对列表 A 里的每一个元素,将其乘以二的结果添加到 B 的尾部」。

PS: 对于每一个可以用多种途径实现的用例,我基本上都可以确定一个最优的途径。

Python 全栈开发:python的推导式(列表推导式、字典推导式、集合推导式)

Python 全栈开发:python的推导式(列表推导式、字典推导式、集合推导式)

推导式comprehensions(又称解析式),是Python的一种独有特性。推导式是可以从一个数据序列构建另一个新的数据序列的结构体。

  • 列表(list)推导式
  • 字典(dict)推导式
  • 集合(set)推导式

列表推导式

一、使用[]生成list

基本格式

var = [expression for item in iterable if condition]
expression        # 列表生成元素表达式,可以是有返回值的函数。
for item in iterable    #迭代iterable将item传入expression表达式中。
if condition    #根据条件过滤数据,生成想得到的数据

eg:列表生成式

var =[item for item in range(10) if item % 2 == 0]
print(var)

# 输出
[0, 2, 4, 6, 8] # 输出为列表

 

二、使用()生成generator

将列表推导式的 [] 换成 () 即可得到  生成器

eg:生成器表达式

gen=(''egg%s'' %i for i in range(10) if i > 5)
print(gen)
print(list(gen))

# 输出
<generator object <genexpr> at 0x7f4b7c219d58> # 生成器对象
[''egg6'', ''egg7'', ''egg8'', ''egg9'']    # 生成器内的数据

 

 

字典推导式

字典推导和列表推导的使用方法是类似的,只不中括号该改成大括号。直接举例说明

eg:大小写key合并

mcase = {''a'': 10, ''b'': 34, ''A'': 7, ''Z'': 3}
mcase_frequency = {
    k.lower(): mcase.get(k.lower(), 0) + mcase.get(k.upper(), 0)
    for k in mcase.keys()
    if k.lower() in [''a'',''b'']
}
print mcase_frequency

# 输出结果
 {''a'': 17, ''b'': 34}

eg:快速更换key和value

mcase = {''a'': 10, ''b'': 34}
mcase_frequency = {v: k for k, v in mcase.items()}
print mcase_frequency
# 输出结果 {10: ''a'', 34: ''b''}

 

集合推导式

跟列表推导式也是类似的。 唯一的区别在于它使用大括号{}。

eg:

squared = {x**2 for x in [1, 1, 2]}
print(squared)
# 输出结果
# set([1, 4])

 

今天关于在Python中,使用列表推导或for-each循环会更好吗?列表for循环 python的介绍到此结束,谢谢您的阅读,有关python – 仅使用列表推导构建列表,没有功能、python – 如何使用两个’for’来枚举列表推导?、Python 中列表推导(list comprehension)相对于循环有什么优势?性能会更高吗?、Python 全栈开发:python的推导式(列表推导式、字典推导式、集合推导式)等更多相关知识的信息可以在本站进行查询。

本文标签: