views:

124

answers:

5

I have this list:

names = ['john','Jonh','james','James','Jardel']

I want loop over the list and handle consecutive names with a case insensitive match in the same iteration. So in the first iteration I would do something with'john' and 'John' and I want the next iteration to start at 'james'.

I can't think of a way to do this using Python's for loop, any suggestions?

+3  A: 
names = ['john','John','james','James']
for name, capitalized_name in zip(names[::2], names[1::2]):
    print name, capitalized_name

Note that you need an even amount of items for this to work properly.

Or (maybe better; hard to tell with little context) use a set to filter the list to contain only unique names (note that this loses order):

>>> names = ['john','John','james','James','Jardel']
>>> unique_names = set([x.lower() for x in names])
>>> for unique_name in unique_names:
...     print unique_name
... 
jardel
james
john
ChristopheD
A: 

You could just use a while loop:

i = 0
while i < len(names):
  # compare names[i] with names[i + 1]
  i = i + 2 # or + 1 if names not equal, for example

Or are you looking for something a bit more involved?

Justin Ethier
+6  A: 

This would be one for itertools.groupby, which groups consecutive equal elements from a list or other iterable. you can specify a function to do the comparison, so that, in your case, the same name in different cases can still be counted as the same thing.

for k, g in itertools.groupby(names, lambda s: s.lower()):
    # Example: in the first iteration:
    #  k = "john"
    #  g = an iterator over ["john", "John"]
    # Process them as you like
David Zaslavsky
How do I use the g var? I tried to print it but I get this:<itertools._grouper object at 0x00B619D0>I'm obviously a noob in python so please don't hate me :)
hdx
That's because it's an iterator object. You could use it in a for loop or a list comprehension (like `[name for name in g]`) and you'll get the names out of it, but if you try to use it without iterating over it, it'll just show up as an iterator, as you saw. To print out the list of names, you could use `print list(g)` which converts it to a list before printing.
David Zaslavsky
`g` is an iterator over the items in the current group. You could iterate over it in a `for` loop or a list comprehension or turn it into a list with `list(g)`. One possible thing to do would be to print out the names in the current group separated by commas: print `', '.join(g)`, which works because the `join` method works with any iterable.
Will McCutchen
@hdx: perhaps it helps to know that input to `groupby()` must be sorted. The list you show is sorted in a case-insensitive manner, but if it wasn't then you can do something like: `for k,g in groupby(sorted(names, key=lambda x:x.lower()), lambda x: x.lower()):`
Adam Bernier
A: 

As you iterate thru the loop, you could try keeping track of the previous name in the list. At the same time, when you're going to store the names, you can make a call to lower() or capitalize() to make the formatting of each name consistent so that you can compare them easier.

e.g.

first = True
prev= ""
for name in names:
    if first:                         #First iteration
        prev = name.lower()           #Need to get the first elem
        do_something_to(curr)
        first = False
    else:
        if prev == name.lower():
             print "do nothing"
        else:
             do_something_to(curr)
        prev = name.lower()

May not be the most efficient, but works.

kchau
A: 

My $0.02:

def byPairs(li):
    for i in xrange(1, len(li), 2):
        yield (li[i-1], li[i])

for a,b in byPairs(names):
    if a.lower()==b.lower():
        doSomething(a,b)

I'm not sure I understood the question exactly; what are you trying to accomplish?

Hugh Bothwell