I want to know how can I remove consecutive value in list or string.
我想知道如何删除列表或字符串中的连续值。
If my list is:
如果我的清单是:
mylist = ["N","N","J","N","J","S","S","K","K","K","A","K"]
I should get:
我应该得到:
["N","J","N","J","S","K","A","K"]
5 个解决方案
#1
4
You can use list comprehensions
您可以使用列表推导
>>> mylist = ["N","N","J","N","J","S","S","K","K","K","A","K"]
>>> [j for i, j in enumerate(mylist) if j != mylist[i-1] or i == 0]
['N', 'J', 'N', 'J', 'S', 'K', 'A', 'K']
#2
3
you can use groupby from itertools
你可以使用itertools中的groupby
In [28]: from itertools import groupby
In [30]: lst
Out[30]: ['N', 'N', 'J', 'N', 'J', 'S', 'S', 'K', 'K', 'K', 'A', 'K']
In [31]: [elem[0] for elem in groupby(lst)]
Out[31]: ['N', 'J', 'N', 'J', 'S', 'K', 'A', 'K']
Performance
性能
In [33]: %timeit [j for i, j in enumerate(lst) if j != lst[i-1]]
100000 loops, best of 3: 2.8 µs per loop
In [34]: %timeit [elem[0] for elem in groupby(lst)]
100000 loops, best of 3: 2.55 µs per loop
In [36]: %timeit list(map(lambda x: x[0], filter(lambda x: x[0] != x[1], zip(lst,lst[1:]+['']))))
100000 loops, best of 3: 9.35 µs per loop
#3
0
Using map
, filter
and zip
is very instructive:
使用map,filter和zip非常有启发性:
>>> list(map(lambda x: x[0], filter(lambda x: x[0] != x[1], zip(mylist,mylist[1:]+['']))))
['N', 'J', 'N', 'J', 'S', 'K', 'A', 'K']
#4
0
You're looking for the unique_justseen
recipe from the itertools
docs:
您正在寻找itertools文档中的unique_justseen配方:
def unique_justseen(iterable, key=None):
"List unique elements, preserving order. Remember only the element just seen."
# unique_justseen('AAAABBBCCDAABBB') --> A B C D A B
# unique_justseen('ABBCcAD', str.lower) --> A B C A D
return map(next, map(itemgetter(1), groupby(iterable, key)))
Source: https://docs.python.org/3/library/itertools.html#itertools-recipes
资料来源:https://docs.python.org/3/library/itertools.html#itertools-recipes
#5
0
1. The List Problem
1.列表问题
You can do that using Python's built-in reduce
function, with assumption that you have at least one element in your list:
你可以使用Python的内置reduce函数来做到这一点,假设你的列表中至少有一个元素:
reduce(lambda lst, el: lst if lst[-1] == el else lst + [el], mylist[1:], [mylist[0]])
So what you basically do here is initialise a new list containing the first element of your original list. Then using reduce
you iterate over the rest of the elements one-by-one and apply the function supplied to reduce
. Wht that function does, is simply check, whether the current element is equal to the last element of the aggregated one. If it is equal, it ignores the current element, by returning just the aggregated list, otherwise, it appends it to the aggregated list and returns.
所以你在这里基本上做的是初始化一个包含原始列表的第一个元素的新列表。然后使用reduce,逐个遍历其余元素并应用提供的函数reduce。该函数所做的只是检查当前元素是否等于聚合元素的最后一个元素。如果它相等,则通过仅返回聚合列表来忽略当前元素,否则,它将其附加到聚合列表并返回。
2. The Brackets Problem
2.括号问题
As for your brackets problem, you can use the filter
built-in function, with a help of custom stack handling in a classic way:
至于括号问题,您可以使用过滤器内置函数,以经典方式处理自定义堆栈处理:
print(filter(escaped, mystr))
where escaped
is defined in the following way:
其中escape的定义方式如下:
bracket_stack = []
def escaped(c):
ignore = False
if c in ['(', '[', '<']:
bracket_stack.append(c)
ignore = True
elif bracket_stack and c in [')', ']', '>']:
ignore = True
if c == ')' and bracket_stack[-1] == '(':
bracket_stack.pop()
if c == ']' and bracket_stack[-1] == '[':
bracket_stack.pop()
if c == '>' and bracket_stack[-1] == '<':
bracket_stack.pop()
in_brackets = len(bracket_stack)
return not (ignore or in_brackets)
#1
4
You can use list comprehensions
您可以使用列表推导
>>> mylist = ["N","N","J","N","J","S","S","K","K","K","A","K"]
>>> [j for i, j in enumerate(mylist) if j != mylist[i-1] or i == 0]
['N', 'J', 'N', 'J', 'S', 'K', 'A', 'K']
#2
3
you can use groupby from itertools
你可以使用itertools中的groupby
In [28]: from itertools import groupby
In [30]: lst
Out[30]: ['N', 'N', 'J', 'N', 'J', 'S', 'S', 'K', 'K', 'K', 'A', 'K']
In [31]: [elem[0] for elem in groupby(lst)]
Out[31]: ['N', 'J', 'N', 'J', 'S', 'K', 'A', 'K']
Performance
性能
In [33]: %timeit [j for i, j in enumerate(lst) if j != lst[i-1]]
100000 loops, best of 3: 2.8 µs per loop
In [34]: %timeit [elem[0] for elem in groupby(lst)]
100000 loops, best of 3: 2.55 µs per loop
In [36]: %timeit list(map(lambda x: x[0], filter(lambda x: x[0] != x[1], zip(lst,lst[1:]+['']))))
100000 loops, best of 3: 9.35 µs per loop
#3
0
Using map
, filter
and zip
is very instructive:
使用map,filter和zip非常有启发性:
>>> list(map(lambda x: x[0], filter(lambda x: x[0] != x[1], zip(mylist,mylist[1:]+['']))))
['N', 'J', 'N', 'J', 'S', 'K', 'A', 'K']
#4
0
You're looking for the unique_justseen
recipe from the itertools
docs:
您正在寻找itertools文档中的unique_justseen配方:
def unique_justseen(iterable, key=None):
"List unique elements, preserving order. Remember only the element just seen."
# unique_justseen('AAAABBBCCDAABBB') --> A B C D A B
# unique_justseen('ABBCcAD', str.lower) --> A B C A D
return map(next, map(itemgetter(1), groupby(iterable, key)))
Source: https://docs.python.org/3/library/itertools.html#itertools-recipes
资料来源:https://docs.python.org/3/library/itertools.html#itertools-recipes
#5
0
1. The List Problem
1.列表问题
You can do that using Python's built-in reduce
function, with assumption that you have at least one element in your list:
你可以使用Python的内置reduce函数来做到这一点,假设你的列表中至少有一个元素:
reduce(lambda lst, el: lst if lst[-1] == el else lst + [el], mylist[1:], [mylist[0]])
So what you basically do here is initialise a new list containing the first element of your original list. Then using reduce
you iterate over the rest of the elements one-by-one and apply the function supplied to reduce
. Wht that function does, is simply check, whether the current element is equal to the last element of the aggregated one. If it is equal, it ignores the current element, by returning just the aggregated list, otherwise, it appends it to the aggregated list and returns.
所以你在这里基本上做的是初始化一个包含原始列表的第一个元素的新列表。然后使用reduce,逐个遍历其余元素并应用提供的函数reduce。该函数所做的只是检查当前元素是否等于聚合元素的最后一个元素。如果它相等,则通过仅返回聚合列表来忽略当前元素,否则,它将其附加到聚合列表并返回。
2. The Brackets Problem
2.括号问题
As for your brackets problem, you can use the filter
built-in function, with a help of custom stack handling in a classic way:
至于括号问题,您可以使用过滤器内置函数,以经典方式处理自定义堆栈处理:
print(filter(escaped, mystr))
where escaped
is defined in the following way:
其中escape的定义方式如下:
bracket_stack = []
def escaped(c):
ignore = False
if c in ['(', '[', '<']:
bracket_stack.append(c)
ignore = True
elif bracket_stack and c in [')', ']', '>']:
ignore = True
if c == ')' and bracket_stack[-1] == '(':
bracket_stack.pop()
if c == ']' and bracket_stack[-1] == '[':
bracket_stack.pop()
if c == '>' and bracket_stack[-1] == '<':
bracket_stack.pop()
in_brackets = len(bracket_stack)
return not (ignore or in_brackets)