使用zip映射等效的嵌套列表理解

时间:2016-06-13 18:17:54

标签: python list

下面,我有一个id列表和一个为每个id创建的URL数量列表,使用url_str作为创建的URL的基础。因此,对于身份id2,我预计会有三个网址。我用list comprehension完成了这项工作,这似乎是解决问题的最灵活方式。

但是,我现在正在学习python,并且我对map等同于列表理解感到好奇。

url_str = "www.amazon.com/gp/cdp/member-reviews/"
ids = ['id' + str(x) for x in xrange(1, 5)]
revs = [1, 3, 1, 8]

# ids output
['id1', 'id2', 'id3', 'id4']


# list comprehension
urls_compr = [url_str + id_r + "page=" + str(x)
              for id_r, page in zip(ids, revs)
              for x in xrange(1, page + 1)] 



# output of list comprehension
['www.amazon.com/gp/cdp/member-reviews/id1page=1',
 'www.amazon.com/gp/cdp/member-reviews/id2page=1',
 'www.amazon.com/gp/cdp/member-reviews/id2page=2',
 'www.amazon.com/gp/cdp/member-reviews/id2page=3',
 'www.amazon.com/gp/cdp/member-reviews/id3page=1',
 'www.amazon.com/gp/cdp/member-reviews/id4page=1',
 'www.amazon.com/gp/cdp/member-reviews/id4page=2',
 'www.amazon.com/gp/cdp/member-reviews/id4page=3',
 'www.amazon.com/gp/cdp/member-reviews/id4page=4',
 'www.amazon.com/gp/cdp/member-reviews/id4page=5',
 'www.amazon.com/gp/cdp/member-reviews/id4page=6',
 'www.amazon.com/gp/cdp/member-reviews/id4page=7',
 'www.amazon.com/gp/cdp/member-reviews/id4page=8']

理想情况下,我有一些效果:

urls_map = map(func, ids, revs)

urls_map
['www.amazon.com/gp/cdp/member-reviews/id1page=1',
 'www.amazon.com/gp/cdp/member-reviews/id2page=1',
 'www.amazon.com/gp/cdp/member-reviews/id2page=2',
 'www.amazon.com/gp/cdp/member-reviews/id2page=3',
 'www.amazon.com/gp/cdp/member-reviews/id3page=1',
 'www.amazon.com/gp/cdp/member-reviews/id4page=1',
 'www.amazon.com/gp/cdp/member-reviews/id4page=2',
 'www.amazon.com/gp/cdp/member-reviews/id4page=3',
 'www.amazon.com/gp/cdp/member-reviews/id4page=4',
 'www.amazon.com/gp/cdp/member-reviews/id4page=5',
 'www.amazon.com/gp/cdp/member-reviews/id4page=6',
 'www.amazon.com/gp/cdp/member-reviews/id4page=7',
 'www.amazon.com/gp/cdp/member-reviews/id4page=8']

我只是不确定func部分。

3 个答案:

答案 0 :(得分:2)

请记住,如果您希望将函数映射到序列的每个元素,则map在列表理解存在之前就已存在,例如:

map(func, seq)

相当于:

[func(x) for x in seq]

尽管在python 3中map返回一个迭代器,所以它更靠近(func(x) for x in seq),用圆括号表示生成器。

列表理解还带来了额外的好处,即能够使用表达式以及/而不是callables。

例如,如果你想为列表的每个元素添加一个(+1),你可以这样做:

[x + 1 for x in seq]

使用map重写它,你需要创建一个可以在参数中添加一个的callable:

map(lambda x:x+1, seq)

更进一步,在列表推导中使用多个变量非常简单:

[x+y for x,y in itertools.product(range(5), range(7))]

但是map的可调用只需要一个参数,所以你需要使用元组将这些元素打包在一起:

map((lambda pair: pair[0] + pair[1]), itertools.product(range(5),range(7)))

你的情况更容易引起混淆,因为序列只是用嵌套的for循环构建的,所以你很可能最终会使用生成器表达式来完成序列:

map((lambda x: x[0] + x[1] + "page=" + str(x[2])), ((url_str, id_r, x) for id_r, page in zip(ids, revs) for x in xrange(1, page + 1)))

这显然不是map的目的,我建议你坚持使用列表理解,因为它是适合你工作的工具。

答案 1 :(得分:1)

我不认为map会在这里以一种很好的方式发挥作用,但在我放弃它之后,我至少能够将列表组合简化为更具可读性和效率的东西: / p>

In [31]: ids = xrange(1, 5)

In [32]: pages = (1, 3, 1, 8)

In [33]: pages_per_id = zip(ids, pages)

In [34]: url_str
Out[34]: 'www.amazon.com/gp/cdp/member-reviews/id%s?page=%s'

In [35]: [url_str % (id, page_no) for id, pages in pages_per_id for page_no in range(1, pages+1)]
Out[35]:
['www.amazon.com/gp/cdp/member-reviews/id1?page=1',
 'www.amazon.com/gp/cdp/member-reviews/id2?page=1',
 'www.amazon.com/gp/cdp/member-reviews/id2?page=2',
 'www.amazon.com/gp/cdp/member-reviews/id2?page=3',
 'www.amazon.com/gp/cdp/member-reviews/id3?page=1',
 'www.amazon.com/gp/cdp/member-reviews/id4?page=1',
 'www.amazon.com/gp/cdp/member-reviews/id4?page=2',
 'www.amazon.com/gp/cdp/member-reviews/id4?page=3',
 'www.amazon.com/gp/cdp/member-reviews/id4?page=4',
 'www.amazon.com/gp/cdp/member-reviews/id4?page=5',
 'www.amazon.com/gp/cdp/member-reviews/id4?page=6',
 'www.amazon.com/gp/cdp/member-reviews/id4?page=7',
 'www.amazon.com/gp/cdp/member-reviews/id4?page=8']

答案 2 :(得分:0)

我不想删除这个问题,因为有人能够在上面的评论中回答我的问题。

 map((lambda x: x[0] + x[1] + "page=" + str(x[2])), ((url_str, id_r, x) for id_r, page in zip(ids, revs) for x in xrange(1, page + 1)))