Blog coding and discussion of coding about JavaScript, PHP, CGI, general web building etc.

Saturday, August 6, 2016

Python

Python "Every Other Element" Idiom


I feel like I spend a lot of time writing code in Python, but not enough time creating Pythonic code. Recently I ran into a funny little problem that I thought might have an easy, idiomatic solution. Paraphrasing the original, I needed to collect every sequential pair in a list. For example, given the list [1,2,3,4,5,6], I wanted to compute [(1,2),(3,4),(5,6)].

I came up with a quick solution at the time that looked like translated Java. Revisiting the question, the best I could do was

l = [1,2,3,4,5,6]  [(l[2*x],l[2*x+1]) for x in range(len(l)/2)]  

which has the side effect of tossing out the last number in the case that the length isn't even.

Is there a more idiomatic approach that I'm missing, or is this the best I'm going to get?

Answer by RichieHindle for Python "Every Other Element" Idiom


This will do it a bit more neatly:

>>> data = [1,2,3,4,5,6]  >>> zip(data[0::2], data[1::2])  [(1, 2), (3, 4), (5, 6)]  

(but it's arguably less readable if you're not familiar with the "stride" feature of ranges).

Like your code, it discards the last value where you have an odd number of values.

Answer by Isaac for Python "Every Other Element" Idiom


How about using the step feature of range():

[(l[n],l[n+1]) for n in range(0,len(l),2)]  

Answer by Ignacio Vazquez-Abrams for Python "Every Other Element" Idiom


The one often-quoted is:

zip(*[iter(l)] * 2)  

Answer by prasanna for Python "Every Other Element" Idiom


try this

def pairs(l, n):      return zip(*[l[i::n] for i in range(n)])  

So,

pairs([1, 2, 3, 4], 2) gives

[(1, 2), (3, 4)]  

Answer by Mike Graham for Python "Every Other Element" Idiom


I usually copy the grouper recipe from the itertools documentation into my code for this.

def grouper(n, iterable, fillvalue=None):      "grouper(3, 'ABCDEFG', 'x') --> ABC DEF Gxx"      args = [iter(iterable)] * n      return izip_longest(fillvalue=fillvalue, *args)  

Answer by Kamil Szot for Python "Every Other Element" Idiom


If you don't want to lose elements if their number in list is not even try this:

>>> l = [1, 2, 3, 4, 5]  >>> [(l[i],  l[i+1] if i+1 < len(l) else None)  for i in range(0, len(l), 2)]  [(1, 2), (3, 4), (5, None)]  

Answer by moshez for Python "Every Other Element" Idiom


The right thing is probably not to compute lists, but to write an iterator->iterator function. This is more generic -- it works on every iterable, and if you want to "freeze" it into a list, you can use the "list()" function.

def groupElements(iterable, n):      # For your case, you can hardcode n=2, but I wanted the general case here.      # Also, you do not specify what to do if the       # length of the list is not divisible by 2      # I chose here to drop such elements      source = iter(iterable)      while True:          l = []          for i in range(n):              l.append(source.next())          yield tuple(l)  

I'm surprised the itertools module does not already have a function for that -- perhaps a future revision. Until then, feel free to use the version above :)

Answer by beardc for Python "Every Other Element" Idiom


toolz is a well-built library with many functional programming niceties overlooked in itertools. partition solves this (with an option to pad the last entry for lists of odd length)

>>> list(toolz.partition(2, [1,2,3,4,5,6]))  [(1, 2), (3, 4), (5, 6)]  


Fatal error: Call to a member function getElementsByTagName() on a non-object in D:\XAMPP INSTALLASTION\xampp\htdocs\endunpratama9i\www-stackoverflow-info-proses.php on line 72

0 comments:

Post a Comment

Popular Posts

Powered by Blogger.