Python 如果尚未存在,则将 id 附加到列表中

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/17370984/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-19 08:00:49  来源:igfitidea点击:

Appending an id to a list if not already present

python

提问by user2341103

I am trying to check if id is in a list and append the id only if its not in the list using the below code..however I see that the id is getting appended even though id is already present in the list.. can anyone provide inputs on what is wrong here?

我正在尝试检查 id 是否在列表中,并且仅当它不在列表中时才附加 id 使用下面的代码..但是我看到即使 id 已经存在于列表中,id 也被附加了 .. 任何人都可以提供有关这里出了什么问题的输入?

   list = ['350882 348521 350166\r\n']
    id = 348521
    if id not in list:
        list.append(id)
    print list

OUTPUT:-
['350882 348521 350166\r\n', 348521]

回答by John

What you are trying to do can almost certainly be achieved with a set.

您尝试做的事情几乎肯定可以通过一组来实现。

>>> x = set([1,2,3])
>>> x.add(2)
>>> x
set([1, 2, 3])
>>> x.add(4)
>>> x.add(4)
>>> x
set([1, 2, 3, 4])
>>> 

using a set's add method you can build your unique set of ids very quickly. Or if you already have a list

使用 set 的 add 方法,您可以非常快速地构建您唯一的 id 集。或者如果你已经有一个清单

unique_ids = set(id_list)

as for getting your inputs in numeric form you can do something like

至于以数字形式获取输入,您可以执行以下操作

>>> ids = [int(n) for n in '350882 348521 350166\r\n'.split()]
>>> ids
[350882, 348521, 350166]

回答by sedavidw

Your id variable is a number where your list only has one element. It's a string that contains your other IDs. You either need to check if id is in that string, or pull the numbers out of the string and store them in the list separately

您的 id 变量是一个数字,其中您的列表只有一个元素。这是一个包含您的其他 ID 的字符串。您要么需要检查 id 是否在该字符串中,要么从字符串中取出数字并将它们分别存储在列表中

list  = [350882, 348521, 350166]

回答by Mark Tolonen

Your list just contains a string. Convert it to integer IDs:

您的列表只包含一个字符串。将其转换为整数 ID:

L = ['350882 348521 350166\r\n']

ids = [int(i) for i in L[0].strip().split()]
print(ids)
id = 348521
if id not in ids:
    ids.append(id)
print(ids)
id = 348522
if id not in ids:
    ids.append(id)
print(ids)
# Turn it back into your odd format
L = [' '.join(str(id) for id in ids) + '\r\n']
print(L)

Output:

输出:

[350882, 348521, 350166]
[350882, 348521, 350166]
[350882, 348521, 350166, 348522]
['350882 348521 350166 348522\r\n']

回答by JoshG79

I agree with other answers that you are doing something weird here. You have a list containing a string with multiple entries that are themselves integers that you are comparing to an integer id.

我同意其他答案,即您在这里做了一些奇怪的事情。您有一个包含多个条目的字符串的列表,这些条目本身就是您要与整数 id 进行比较的整数。

This is almost surely not what you should be doing. You probably should be taking input and converting it to integers before storing in your list. You could do that with:

这几乎肯定不是你应该做的。在存储到列表中之前,您可能应该接收输入并将其转换为整数。你可以这样做:

input = '350882 348521 350166\r\n'
list.append([int(x) for x in input.split()])

Then your test will pass. If you really are sure you don't want to do what you're currently doing, the following should do what you want, which is to not add the new id that already exists:

那么你的测试就会通过。如果你真的确定你不想做你目前正在做的事情,下面应该做你想做的,也就是不要添加已经存在的新 id:

list = ['350882 348521 350166\r\n']
id = 348521
if id not in [int(y) for x in list for y in x.split()]:
    list.append(id)
print list

回答by dav

If you really don't want to change your structure, or at least create a copy of it containing the same data (e.g. make a class property with a setter and getter that read from/write to that string behind the scenes), then you can use a regular expression to check if an item is in that "list" at any given time, and if not, append it to the "list" as a separate element.

如果你真的不想改变你的结构,或者至少创建一个包含相同数据的副本(例如,使用 setter 和 getter 创建一个在幕后读取/写入该字符串的类属性),那么你可以使用正则表达式在任何给定时间检查某个项目是否在该“列表”中,如果不在,则将其作为单独的元素附加到“列表”中。

if not re.match("\b{}\b".format(348521), some_list[0]): some_list.append(348521)

if not re.match("\b{}\b".format(348521), some_list[0]): some_list.append(348521)

This is probably faster than converting it to a set every time you want to check if an item is in it. But using setas others have suggested here is a million times better.

这可能比每次要检查项目是否在其中时将其转换为集合更快。但是set像其他人在这里建议的那样使用要好一百万倍。

回答by Atihska

A more pythonic way, without using set is as follows:

一种更pythonic的方式,不使用set如下:

lst = [1, 2, 3, 4]
lst.append(3) if 3 not in lst else lst

回答by Austen Hoogen

There are a couple things going on with your example. You have a list containing a string of numbers and newline characters:

你的例子有几件事情正在发生。您有一个包含一串数字和换行符的列表:

list = ['350882 348521 350166\r\n']

And you are trying to find a number ID within this list:

并且您正在尝试在此列表中查找数字 ID:

id = 348521
if id not in list:
    ...

Your first conditional is always going to pass, because it will be looking for integer 348521in listwhich has one element at index list[0]with the string value of '350882 348521 350166\r\n', so integer 348521 will be added to that list, making it a list of two elements: a string and an integer, as your output shows.

你的第一个条件总是会通过,因为它会寻找整数348521list其在索引一个元素的list[0]使用的字符串值'350882 348521 350166\r\n',所以整数348521将被添加到列表中,使其成为两个元素的列表:字符串,一个整数,如您的输出所示。

To reiterate: list is searched for id, not the string in list's first element.

重申:列表搜索的是 id,而不是列表第一个元素中的字符串。

If you were trying to find if the string representation of '348521'was contained within the larger string contained within your list, you could do the following, noting that you would need to do this for each element in list:

如果您试图查找 的字符串表示形式'348521'是否包含在列表中包含的较大字符串中,您可以执行以下操作,注意您需要对 中的每个元素执行此操作list

if str(id) not in list[0]: # list[0]: '350882 348521 350166\r\n'
    ...                    #                  ^^^^^^

However be aware that you would need to wrap str(id)with whitespace for the search, otherwise it would also match:

但是请注意,您需要str(id)使用空格进行搜索,否则它也会匹配:

2348521999
 ^^^^^^

It is unclear whether you want your "list" to be a "string of integers separated by whitespace" or if you really want a list of integers.

目前尚不清楚您是否希望您的“列表”是“由空格分隔的整数字符串”,或者您是否真的想要一个整数列表。

If all you are trying to accomplish is to have a list of IDs, and to add IDs to that list only if they are not already contained, (and if the order of the elements in the list is not important,) then a set would be the best data structure to use.

如果您想要完成的只是拥有一个 ID 列表,并且仅当 ID 尚未包含时才将其添加到该列表中(并且如果列表中元素的顺序不重要),那么集合将是最好的数据结构。

ids = set(
    [int(id) for id in '350882 348521 350166\r\n'.strip().split(' ')]
)

# Adding an ID already in the set has no effect
ids.add(348521)

If the ordering of the IDs in the string is importantthen I would keep your IDs in a standard list and use your conditional check:

如果字符串中 ID 的顺序很重要,那么我会将您的 ID 保存在标准列表中并使用您的条件检查:

ids = [int(id) for id in '350882 348521 350166\r\n'.strip().split(' ')]

if 348521 not in ids:
    ...