Python:remove()不';它似乎起作用了
我找了一会儿,但找不到解决问题的办法。我对Python还是新手,所以有时我会和一些显而易见的事情做斗争。。。提前感谢您的建议 我有一个包含对象和这些对象的副本的列表,它们都有特定的名称:Python:remove()不';它似乎起作用了,python,Python,我找了一会儿,但找不到解决问题的办法。我对Python还是新手,所以有时我会和一些显而易见的事情做斗争。。。提前感谢您的建议 我有一个包含对象和这些对象的副本的列表,它们都有特定的名称:objects\u ext和duplicatedObject\u SREF\u ext。我想要的是,如果列表中有重复的对象,请检查原始对象是否也在列表中,如果在列表中,请从列表中删除重复的对象 我尝试使用remove()方法,因为列表中每个名称只能出现一次,但不起作用。这是我的密码: rawSelection =
objects\u ext
和duplicatedObject\u SREF\u ext
。我想要的是,如果列表中有重复的对象,请检查原始对象是否也在列表中,如果在列表中,请从列表中删除重复的对象
我尝试使用remove()
方法,因为列表中每个名称只能出现一次,但不起作用。这是我的密码:
rawSelection = [u'crapacruk_high', u'doubidou_high', u'blahbli_high', u'crapacruk_SREF_high', u'doubidou_SREF_high', u'blahbli_SREF_high']
# objects with '_SREF_' in their names are the duplicated ones
for obj in rawSelection:
if '_SREF_' in str(obj):
rawName = str(obj).split('_')
rootName = rawName [0]
defName = rootName + '_' + '_'.join(rawName[2:])
if defName in rawSelection:
rawSelection.remove (obj)
# Always returns:
# [u'crapacruk_high', u'doubidou_high', u'blahbli_high', u'doubidou_SREF_high']
# Instead of:
# [u'crapacruk_high', u'doubidou_high', u'blahbli_high']
编辑:哦,忘了说只有原始对象也在列表中时,才必须从列表中删除重复对象。您可以将for循环从列表中对象的
转到列表中对象的(对象选择):
。这将修复您在迭代列表副本时遇到的问题。这样做的方式是,在对列表进行迭代时修改列表,从而导致出现问题
rawSelection = [u'crapacruk_high', u'doubidou_high', u'blahbli_high', u'crapacruk_SREF_high', u'doubidou_SREF_high', u'blahbli_SREF_high']
for obj in list(rawSelection):
if '_SREF_' in str(obj):
rawName = str(obj).split('_')
rootName = rawName [0]
defName = rootName + '_' + '_'.join(rawName[2:])
if defName in rawSelection:
rawSelection.remove (obj)
print(rawSelection)
这将满足您的要求(请注意,项目的显示顺序无关紧要):
这是通过迭代原始列表,并从每个项目中删除“u SREF”
子字符串来实现的。然后将每个编辑的字符串对象添加到集合
理解中(这就是{}
括号的意思:正在创建一个新的集合
对象)。然后,将集合
对象转换回列表
对象
这是因为对于set
对象,不能有重复项,因此当尝试添加重复项时,它会失败(无声)。请注意,原始项目的顺序不保留
编辑:正如@peterdegloper在评论中指出的那样,这不适用于仅当原始项出现时才删除\u SREF
项的约束。为此,我们将执行以下操作:
no_SREF_Set = {i for i in rawSelection if '_SREF_' not in i}
rawSelection = list({i.replace('_SREF', '') if i.replace('_SREF', '') in no_SREF_Set else i for i in rawSelection})
你可以把它组合成一行,但对我来说有点长:
rawSelection = list({i.replace('_SREF', '') if i.replace('_SREF', '') in {i for i in rawSelection if '_SREF_' not in i} else i for i in rawSelection})
这是通过创建一个没有“u SREF”
的项目的集合
,然后创建一个新的列表
(与上述类似),该列表仅在无SREF>集合中出现项目的无“u SREF”
版本时替换“u SREF”
问题在于,您正在对迭代的同一个列表进行变异
当您从列表中删除u'crapacruk\u SREF\u high'
时,它之后的所有内容都会向左移动(这在C源代码级别上完成),因此obj
的值现在是u'doubidou\u SREF\u high'
。然后for循环结束,obj
成为列表中的下一个元素,u'blahbli\u SREF\u high'
要解决此问题,您可以复制列表并获取
for obj in rawSelection[:]:
...
将问题分解为子任务
def get_orig_name(name):
if '_SREF_' in name:
return '_'.join(name.split('_SREF_'))
else:
return name
然后构造一个没有DUP的新列表
rawSelection = [u'crapacruk_high',
u'doubidou_high',
u'blahbli_high',
u'crapacruk_SREF_high',
u'doubidou_SREF_high',
u'blahbli_SREF_high']
uniqueList = [ n for n in rawSelection if ('_SREF_' not in n) or
(get_orig_name(n) not in rawSelection ) ]
print uniqueList
您可以使用过滤器
获得相当干净的解决方案
def non_duplicate(s):
return not('_SREF_' in s and s.replace('_SREF', '') in raw_selection)
filtered_selection = filter(non_duplicate, raw_selection)
修改列表时不要迭代列表。这是行不通的。从列表
对象创建集
对象会更好。它将删除重复项:newobj=set(mylist)
EDIT:nevermind。没有意识到字符串是不一样的。@Morgan Thrapp你有其他选择吗?也许用发电机?感谢u'doubidou'u high'
总是在“u SREF”
版本之前出现吗?rawSelection=[x代表x,如果“\u SREF”不在x或x.replace(“'u SREF',”)不在rawSelection中]
实际上,不,这违反了“只有原始对象也在列表中时,才能从列表中删除重复对象“。我也不确定是否已经确定不需要保留订单。OP说,复制版本不一定在原始版本之后,但这不完全是同一回事。@PeterdGlopper编辑了答案,以解决您在第一条评论中指出的问题。“不过,秩序确实没有得到维护。”斯图尔特正在工作。早些时候从控制台复制的错误。@PeterdGlopper我早些时候做的编辑有一个错误。现在是对的。
def non_duplicate(s):
return not('_SREF_' in s and s.replace('_SREF', '') in raw_selection)
filtered_selection = filter(non_duplicate, raw_selection)