I'm writing a small NLP algorithm and I need to do the following:
For every string x in the list ["this", "this", "and", "that"]
, if the string x
and the next string are identical, I want to print the string.
s = ["this", "this", "and", "that"]
for i in xrange(1,len(s)):
if s[i] == s[i-1]:
print s[i]
EDIT:
Just as a side note, if you are using python 3.X use range
instead of xrange
strings = ['this', 'this', 'and', 'that']
for a, b in zip(strings, strings[1:]):
if a == b:
print a
Sometimes, I like to stick with old-fashioned loops:
strings = ['this', 'this', 'and', 'that']
for i in range(0, len(strings)-1):
if strings[i] == strings[i+1]:
print strings[i]
Everyone knows what's going on without much thinking, and it's fairly efficient...
Most Pythonic is a list comprehension, which is exactly built for looping and testing at the same time:
>>> strings = ['this', 'this', 'and', 'that']
>>> [a for (a,b) in zip(strings, strings[1:]) if a==b]
['this']
Or, to avoid temporary objects (h/t @9000):
>>> import itertools as it
>>> [a for (a,b) in it.izip(strings, it.islice(strings,1)) if a==b]
['this']
TEST = ["this", "this", "and", "that"]
for i, s in enumerate(TEST):
if i > 0 and TEST[i-1] == s:
print s
# Prints "this"
why not simply ? :
strings = ['this', 'this', 'and', 'that', 'or', 'or', 12,15,15,15, 'end']
a = strings[0]
for x in strings:
if x==a:
print x
else:
a = x
Is that homework?
l = ["this", "this", "and", "that", "foo", "bar", "bar", "baz"]
for i in xrange(len(l)-1):
try:
if l.index(l[i], i+1) == i+1:
print l[i]
except ValueError:
pass
Generally speaking, if you're processing over items in a list and you need to look at the current item's neighbors, you're going to want to use enumerate
, since enumerate
gives you both the current item and its position in the list.
Unlike the approaches that use zip
, this list comprehension requires no duplication of the list:
print [s for i, s in enumerate(test[:-1]) if s == test[i + 1]]
Note that it fails if there aren't at least two elements in test
, and that test
must be a list. (The zip
approaches will work on any iterable.)
Here's a little different approach that uses a special class to detect repeats in a sequence. Then you can actually find the repeats using a simple list comprehension.
class repeat_detector(object):
def __init__(self, initial=None):
self.last = initial
def __call__(self, current):
if self.last == current:
return True
self.last = current
return False
strings = ["this", "this", "and", "that"]
is_repeat = repeat_detector()
repeats = [item for item in strings if is_repeat(item)]
Use the recipe for pairwise()
from the stdlib itertools documentation (I'll quote it here):
def pairwise(iterable):
"s -> (s0,s1), (s1,s2), (s2, s3), ..."
a, b = tee(iterable)
next(b, None)
return izip(a, b)
And you can do:
for a, b in pairwise(L):
if a == b:
print a
Or with a generator expression thrown in:
for i in (a for a, b in pairwise(L) if a==b):
print i
精彩评论