本练习取自Google's Python Class:
d。给定一个数字列表,返回一个列表 所有相邻的==元素都被缩减为单个元素, 所以[1,2,3,3]返回[1,2,3]。您可以创建一个新列表或 修改传入的列表。
到目前为止,这是我的解决方案:
def remove_adjacent(nums):
if not nums:
return nums
list = [nums[0]]
for num in nums[1:]:
if num != list[-1]:
list.append(num)
return list
但这看起来更像是一个C程序而不是Python脚本,我觉得这可以做得更优雅。
修改
所以[1, 2, 2, 3]
应该[1, 2, 3]
而[1, 2, 3, 3, 2]
应该[1, 2, 3, 2]
答案 0 :(得分:9)
itertools中的功能可以在这里运行:
import itertools
[key for key,seq in itertools.groupby([1,1,1,2,2,3,4,4])]
你也可以写一个发电机:
def remove_adjacent(items):
# iterate the items
it = iter(items)
# get the first one
last = next(it)
# yield it in any case
yield last
for current in it:
# if the next item is different yield it
if current != last:
yield current
last = current
# else: its a duplicate, do nothing with it
print list(remove_adjacent([1,1,1,2,2,3,4,4]))
答案 1 :(得分:3)
itertools
救援。
import itertools
def remove_adjacent(lst):
i = iter(lst)
yield next(i)
for x, y in itertools.izip(lst, i):
if x != y:
yield y
L = [1, 2, 2, 3]
print list(remove_adjacent(L))
答案 2 :(得分:3)
使用列表推导的解决方案,压缩然后迭代两次。效率低,但短而甜。它还有一个扩展[1:]的问题。
a = [ 1,2,2,2,3,4,4,5,3,3 ]
b = [ i for i,j in zip(a,a[1:] + [None]) if not i == j ]
答案 3 :(得分:2)
这样可行,但我对它不太满意,因为+[None]
位确保最后一个元素也被返回...
>>> mylist=[1,2,2,3,3,3,3,4,5,5,5]
>>> [x for x, y in zip(mylist, mylist[1:]+[None]) if x != y]
[1, 2, 3, 4, 5]
最恐怖的方式可能是走阻力最小的路径,并按照THC4K的建议使用itertools.groupby()
并完成它。
答案 4 :(得分:1)
>>> def collapse( data ):
... return list(sorted(set(data)))
...
>>> collapse([1,2,2,3])
[1, 2, 3]
添加额外要求后的第二次尝试:
>>> def remove_adjacent( data ):
... last = None
... for datum in data:
... if datum != last:
... last = datum
... yield datum
...
>>> list( remove_adjacent( [1,2,2,3,2] ) )
[1, 2, 3, 2]
答案 5 :(得分:0)
您可能需要查看itertools。另外,这是一个tutorial on Python iterators and generators (pdf)。
答案 6 :(得分:0)
这也有点功能;它可以使用lambdas写成一个单行,但这会让它更加混乱。在Python 3中,您需要从functools导入reduce。
def remove_adjacent(nums):
def maybe_append(l, x):
return l + ([] if len(l) and l[-1] == x else [x])
return reduce(maybe_append, nums, [])