[英]Remove element, and n following elements from list
我想从列表中删除所有
要迭代的元素,跳过与某些测试匹配的元素,并在匹配之后跳过一定数量的元素。 例如。
# skip 'foo' and 2 subsequent values
values = [1, 2, 3, 'foo', 'a', 'b', 6, 7, 'foo', 'x', 'y']
result = [1, 2, 3, 6, 7]
有比使用建立新列表的计数器进行迭代并在找到匹配项时跳过n
迭代进行迭代的更优雅的方法吗? 即。
values = [1, 2, 3, 'foo', 'a', 'b', 6, 7, 'foo', 'x', 'y']
result = []
i = 0
while i < len(values):
if values[i] == 'foo':
i += 3
else:
result.append(values[i])
i += 1
print result
[1, 2, 3, 6, 7]
嗯,发电机怎么样?
def iterskip(iterator, test, n):
"""Iterate skipping values matching test, and n following values"""
iterator = iter(iterator)
while 1:
value = next(iterator)
if test(value):
for dummy in range(n):
next(iterator)
else:
yield value
def is_foo(value):
return value == 'foo'
print list(iterskip(values, is_foo, 2))
只是切片删除。
>>> values = [1, 2, 3, 'foo', 'a', 'b', 6, 7, 'foo', 'x', 'y']
>>> values.index('foo')
3
>>> del values[3:3 + 3]
>>> values.index('foo')
5
>>> del values[5:5 + 3]
>>> values.index('foo')
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ValueError: 'foo' is not in list
>>> values
[1, 2, 3, 6, 7]
现在,有了协程解决方案。
def countdown(val, count):
curr = 0
while True:
now = (yield curr)
if curr > 0:
curr -= 1
if now == val:
curr = count
values = [1, 2, 3, 'foo', 'a', 'b', 6, 7, 'foo', 'x', 'y']
c = countdown('foo', 3)
c.next()
print [x for x in values if not c.send(x)]
编写一个简单的函数来处理列表的del slice:
import copy
def del_sublists(list, value, length, copy_list = False):
if copy_list:
list = copy.deepcopy(list)
while value in list:
del list[list.index(value):list.index(value) + (length + 1)]
return list
a = [1, 2, 3, 'foo', 'a', 'b', 6, 7, 'foo', 'x', 'y']
print del_sublists(a, 'foo', 2)
print a
输出:
[1, 2, 3, 6, 7]
[1, 2, 3, 6, 7]
相同但不更改变量:
a = [1, 2, 3, 'foo', 'a', 'b', 6, 7, 'foo', 'x', 'y']
print del_sublists(a, 'foo', 2, copy_list = True)
print a
输出:
[1, 2, 3, 6, 7]
[1, 2, 3, 'foo', 'a', 'b', 6, 7, 'foo', 'x', 'y']
取决于您对雅致的定义,以及您是否要执行题名所说的(从列表中删除,即不创建新列表)。
下面的第一个函数通过向后迭代并删除不需要的内容来安全地更改现有列表。 第二个函数使用list.index
向前迭代,直到找不到标记为止(IOW Ignacio的答案建议)。 第三个函数是第一个函数的修改版本,假设问题是从字面上理解的,例如['foo', 'foo', 1, 2]
简化为[]
,而不是[2]
。
码:
def inplace_munge_1(alist, query, size):
for i in xrange(len(alist) - 1, -1, -1):
if alist[i] == query:
del alist[i:i+size]
def inplace_munge_2(alist, query, size):
start = 0
while True:
try:
i = alist.index(query, start)
except ValueError:
return
del alist[i:i+size]
start = i
def inplace_munge_3(alist, query, size):
marker = len(alist)
delpos = []
for i in xrange(len(alist) - 1, -1, -1):
if alist[i] == query:
for j in xrange(min(i + size, marker) - 1, i - 1, -1):
delpos.append(j)
marker = i
for j in delpos:
del alist[j]
funcs = [inplace_munge_1, inplace_munge_2, inplace_munge_3]
tests = [
[],
[1],
['foo'],
[1, 2, 3, 'foo', 'a', 'b', 6, 7, 'foo', 'x', 'y'],
['foo', 'foo', 1, 2, 3],
]
fmt = "%-15s: %r"
for test in tests:
print
print fmt % ("Input", test)
for func in funcs:
values = test[:]
func(values, 'foo', 3)
print fmt % (func.__name__, values)
输出:
Input : []
inplace_munge_1: []
inplace_munge_2: []
inplace_munge_3: []
Input : [1]
inplace_munge_1: [1]
inplace_munge_2: [1]
inplace_munge_3: [1]
Input : ['foo']
inplace_munge_1: []
inplace_munge_2: []
inplace_munge_3: []
Input : [1, 2, 3, 'foo', 'a', 'b', 6, 7, 'foo', 'x', 'y']
inplace_munge_1: [1, 2, 3, 6, 7]
inplace_munge_2: [1, 2, 3, 6, 7]
inplace_munge_3: [1, 2, 3, 6, 7]
Input : ['foo', 'foo', 1, 2, 3]
inplace_munge_1: []
inplace_munge_2: [2, 3]
inplace_munge_3: [3]
使用定义的函数的良好解决方案:
def special_remove(my_list, item, start=0):
try:
pos = my_list.index(item, start)
return special_remove(my_list[:pos] + my_list[pos+3:], item, pos)
except ValueError:
return my_list
并将函数与数据一起使用:
>>> values = [1, 2, 3, 'foo', 'a', 'b', 6, 7, 'foo', 'x', 'y']
>>> special_remove(values, 'foo') [1, 2, 3, 6, 7]
这段代码的好处是,即使您要删除超出范围的元素,它也不会失败,例如:
>>> values = [1, 'foo']
>>> special_remove(values, 'foo')
[1]
功能版本:
不过,这有点混乱。
def unfold(f, x):
while True:
try:
w, x = f(x)
except TypeError:
raise StopIteration
yield w
def test(info):
values, cur_values, n = info
length = len(values)
if n == length:
return None
elif n == length-1:
cur_values = cur_values + [values[n]]
elif values[n] == "foo" and n < len(values)-2:
n += 3
return (cur_values, (values, cur_values + [values[n]], n+1))
values = [1, 2, 3, 'a', 'b', 6, 7, 'foo', 'x', 'y', 2 , 6 , 7, "foo", 4 , 5, 6, 7]
results = list(unfold(test, (values, [], 0)))[-1]
print results
输出:[1、2、3,'a','b',6、7、2、6、7、6、7]
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.