简体   繁体   English

如何制作两个列表并根据另一个列表删除元素?

[英]how to make take two lists and remove elements based on another list?

I have three lists.我有三个清单。 Two lists of string, and one list of float.两个字符串列表和一个浮点列表。 I used zip to match one list of string and float together that are the same length to make a new string.我使用 zip 来匹配一个字符串列表并浮动在一起,它们的长度相同以创建一个新字符串。 Basically:基本上:

letters1 = ['a', 'b', 'c', 'd', 'e']
numbers = [0.0, 3.0, 5.0, 10.0, 28.0]
letters2 = ['a', 'c', 'e']
letnum = [i for i in zip(letters1, numbers)]

This gets me: [('a', 0.0), ('b', 3.0), ('c', 5.0), ('d', 10.0), ('e', 28.0)]这让我: [('a', 0.0), ('b', 3.0), ('c', 5.0), ('d', 10.0), ('e', 28.0)]

I want to use the other list to get only [0.0, 5.0, 28.0] , but I don't know how to return a list of float like that.我想使用另一个列表来仅获取[0.0, 5.0, 28.0] ,但我不知道如何返回这样的浮点列表。

I tried using [x for x in letnum if x in letters2] but that gave me [] .我尝试使用[x for x in letnum if x in letters2]但这给了我[]

I also know letnum = [i for _, i in zip(letters1, numbers)] will get me [0.0, 3.0, 5.0, 10.0, 28.0] but I don't know if that does anything.我也知道letnum = [i for _, i in zip(letters1, numbers)]会得到我[0.0, 3.0, 5.0, 10.0, 28.0]但我不知道这是否有任何作用。

Any help would be appreciated!任何帮助,将不胜感激!

Each element in letnum is a tuple which is a pair of a letter and a float. letnum中的每个元素都是一个元组,它是一对字母和一个浮点数。 If you take the first element of the tuple and then check for existence in the letters2 list you will find a match.如果您获取元组的第一个元素,然后检查letters2列表中是否存在,您将找到匹配项。

[x for x in letnum if x[0] in letters2] 

x[0] is taking the first element of the tuple. x[0]正在获取元组的第一个元素。

If you anticipate large lists, here's a linear solution using a lookup dictionary to enable grabbing a float for each element in letters2 in constant time instead of repeatedly iterating in a nested loop.如果您预计列表很大,这里有一个使用查找字典的线性解决方案,可以在恒定时间内为letters2中的每个元素获取浮点数,而不是在嵌套循环中重复迭代。 Total time complexity is O(len(letters) + len(letters2)) which is optimal:总时间复杂度为O(len(letters) + len(letters2)) ,这是最优的:

>>> letters1 = ['a', 'b', 'c', 'd', 'e']
>>> numbers = [0.0, 3.0, 5.0, 10.0, 28.0]
>>> letters2 = ['a', 'c', 'e']
>>> lookup = {x: y for x, y in zip(letters1, numbers)}
>>> [lookup[x] for x in letters2 if x in lookup]
[0.0, 5.0, 28.0]

The reason your original attempt doesn't work is [x for x in letnum if x in letters2] tries to find a whole tuple x in letters2 which only contains strings.您最初的尝试不起作用的原因是[x for x in letnum if x in letters2]试图在letters2中找到一个仅包含字符串的整个元组x

Would you try the following:你会尝试以下方法:

letters1 = ['a', 'b', 'c', 'd', 'e']
numbers = [0.0, 3.0, 5.0, 10.0, 28.0]
letters2 = ['a', 'c', 'e']

d = {}
for i in range(len(letters1)):
    d[letters1[i]] = numbers[i]
letnum = [d[x] for x in letters2]
print(letnum)

Output: Output:

[0.0, 5.0, 28.0]

Let's consider the entire process at once (edited slightly because I misunderstood the requirement)让我们一次考虑整个过程(由于我误解了要求而略有编辑)

for each of the letter and number pairs that we get by zip ping together letters1 and numbers , we want: the number , but only if the letter was in letters2 . for我们通过zipletters1numbers ping 在一起得到的每个letternumber对,我们想要: number ,但前提if letter in letters2字母 2 中。

So, we write it exactly like that, except that the element description goes at the front.所以,我们完全一样地写它,除了元素描述在前面。

[number for letter, number in zip(letters1, numbers) if letter in letter2]

To cover your attempts:为了涵盖您的尝试:

I tried using [x for x in letnum if x in letters2] but that gave me [] .我尝试使用[x for x in letnum if x in letters2]但这给了我[]

Yes, because x is one of the pairs, and letters2 doesn't contain those pairs.是的,因为x是其中一对,而letters2不包含这些对。 You can fix this as in @vaichidrewar's answer by extracting the letter, x[0] , for the comparison.您可以通过提取字母x[0]进行比较来解决此问题,就像@vaichidrewar 的回答一样。 Similarly, x is one of the pairs, and you only want the number, so x[1] extracts the number.同样, x是其中一对,您只需要数字,因此x[1]提取数字。

I also know letnum = [i for _, i in zip(letters1, numbers)] will get me [0.0, 3.0, 5.0, 10.0, 28.0] but I don't know if that does anything.我也知道 letnum = [i for _, i in zip(letters1, numbers)] 会得到我 [0.0, 3.0, 5.0, 10.0, 28.0] 但我不知道这是否有任何作用。

It's a start, in the sense that you are using unpacking for the zip results to give separate names to the elements of each pair that you get.这是一个开始,从某种意义上说,您正在对zip结果进行解包,以便为您获得的每对元素提供单独的名称。 By convention, we use _ to refer to values that we don't care about;按照惯例,我们使用_来指代我们不关心的值; but you do care about both values (because you want the letter for the condition).但是您确实关心这两个值(因为您想要条件的字母)。

convert zip object into list and access 0, 2, 5 index using range(0, len(numbers), 2)zip object转换为list并使用range(0, len(numbers), 2) 0, 2, 5 0、2、5 索引

letters1 = ['a', 'b', 'c', 'd', 'e']
numbers = [0.0, 3.0, 5.0, 10.0, 28.0]
letters2 = ['a', 'c', 'e']
letnum = [list(zip(letters1, numbers))[i] for i in range(0,len(numbers), 2)]

print(letnum)

Methiod-2方法2

letnum = [i for i in zip(letters1, numbers) if i[0] in letters2]

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM