Python 根据第二个列表中的元素对列表进行排序和筛选

Python 根据第二个列表中的元素对列表进行排序和筛选,python,list,Python,List,我有两个列表,第一个包含人名,每个人都与不同的字符关联,例如数字、字母,例如: 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', 'georg

我有两个列表,第一个包含人名,每个人都与不同的字符关联,例如数字、字母,例如:

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(“')
)将人名与其他字符分开,找到它是哪个名字,并使用第二个循环在
listName
中找到它的索引


然而,我想知道是否有一种更简单的方法可以做到这一点,即避免使用循环,只使用理解列表?

对于这个问题,我建议您使用循环,只是为了清楚起见。但是,如果您必须使用列表理解,您可以使用基本相同的方法:

thirdlist = [listName.index(x[:x.find('_')]) for x in listNameAge]

这是一个列表理解,由
listName.index(string.split(“”)[0]
组成,其中
string
listNameAge
string.split(“”)[0]
是从字符串开头到第一个下划线的字符串,因此
listName.index(string.split(“”)[0]
是在
列表名中出现的第一个项目

您可以在
列表名
中获取每个项目,然后在
'
上进行
拆分
,获取拆分的第一部分,然后使用
索引
在第二个列表中查找它

>>> [listName.index(i.split('_')[0]) for i in listNameAge]
[2, 0, 3, 1, 2, 0, 1, 3, 2, 0, 1]

虽然你可以用一行程序来实现这一点,但我认为,为了提高效率,建立一本字典是值得的:

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是另一个列表的长度。

您可以尝试此方法,只要
列表名
出现在
列表名
中,请检查:

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]

我强烈建议不要使用
.index()
,因为它的复杂性是
O(n)
,并且使得此操作的总体复杂性
O(mn)
,其中
m
n
是列表的大小

这是一个使用发电机的快速单行程序:

map(lambda (x,y): y[x[:x.find('_')]],izip(listNameAge, repeat(dict(izip(listName, count())))))
更具可读性的版本是(如Ami所示):


请注意,列表理解(我想你的意思是)仍然涉及循环。嗨,是的,我指的是列表理解。我要避免的是“for loops”和列表理解仍然涉及for loops。我建议你使用字典
{name:index}
为了避免目前答案的时间复杂度太低。你能添加一些解释吗?@Will:我已经添加了一些。如果有任何可能不清楚的地方,请告诉我。太棒了,谢谢!(这会在审阅队列中弹出。只有代码的答案会自动标记。)嗨,谢谢你,这很好,而且很清楚。我的列表不长,所以时间复杂性不是问题。
map(lambda (x,y): y[x[:x.find('_')]],izip(listNameAge, repeat(dict(izip(listName, count())))))
nameMap = dict(izip(listName, xrange(len(listName))))
thirdList = map(lambda x: nameMap[x[:x.find('_')]],listNameAge)