下面,我有一个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
部分。
答案 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)))