我有两个列表,第一个包含人名,每个人都与各种字符相关联,例如数字,字母,例如:
listNameAge = ['alain_90xx', 'fred_10y', 'george_50', 'julia_10l','alain_10_aa', 'fred_90', 'julia_50', 'george_10s', 'alain_50', 'fred_50', 'julia_90']
第二个包含该人的姓名:
listName = ['fred', 'julia', 'alain', 'george']
使用第二个列表,我想将第三个列表与第一个列表相关联,这样第一个列表中的每个名称都与第二个列表中的索引位置相关联,即:
thirdlist = [2, 0, 3, 1, 2, 0, 1, 3, 2, 0, 1]
名称和字符用下划线分隔,但字符可以是任何种类。我可以遍历listNameAge
的元素,使用字符串上的.split('_')
将人名与其他字符分开,找到它的名称并在{{1}中找到它的索引使用第二个循环。
但是我想知道是否有更简单的方法可以做到这一点,即避免使用循环并仅使用理解列表?
答案 0 :(得分:3)
虽然您可以使用单行代码进行此操作,但我认为,为了提高效率,我需要付费才能构建字典:
namePos = dict((name, i) for (i, name) in enumerate(listName))
>>> [namePos[n.split('_')[0]] for n in listNameAge]
[2, 0, 3, 1, 2, 0, 1, 3, 2, 0, 1]
此代码的(预期)运行时间是Θ(m + n)其中 m 是第一个列表的长度, n 另一个的长度。
答案 1 :(得分:2)
对于这个具体的问题,我建议你使用一个循环只是为了清楚。但是,如果必须使用列表推导,则可以基本上以相同的方式执行此操作:
thirdlist = [listName.index(x[:x.find('_')]) for x in listNameAge]
答案 2 :(得分:1)
thirdList = [listName.index(string.split("_")[0]) for string in listNameAge]
这是一个由listName.index(string.split("_")[0]
组成的列表理解,其中为string
中的每个项目定义了listNameAge
。 string.split("_")[0]
是从字符串开头到第一个下划线的字符串,因此listName.index(string.split("_")[0]
是listName
中第一次出现的字符串。
答案 3 :(得分:1)
您可以使用listNameAge
中的每个项目,然后split
上的'_'
,获取拆分的第一部分,然后使用index
在第二个列表中找到它
>>> [listName.index(i.split('_')[0]) for i in listNameAge]
[2, 0, 3, 1, 2, 0, 1, 3, 2, 0, 1]
答案 4 :(得分:1)
您可以尝试此操作,只要在listNameAge
listName
,即可查看
for x in listNameAge:
for y in listName:
if y in x:
thirdList.append(listName.index(y))
结果:
[2, 0, 3, 1, 2, 0, 1, 3, 2, 0, 1]
答案 5 :(得分:1)
我强烈建议不要使用.index()
,因为它的复杂性为O(n)
,并且使O(mn)
和m
的大小合并n
列表。
这是使用发电机的快速单线:
map(lambda (x,y): y[x[:x.find('_')]],izip(listNameAge, repeat(dict(izip(listName, count())))))
更可读的版本(如Ami所示):
nameMap = dict(izip(listName, xrange(len(listName))))
thirdList = map(lambda x: nameMap[x[:x.find('_')]],listNameAge)