Joining pairs of elements of a list

179,482

Solution 1

You can use slice notation with steps:

>>> x = "abcdefghijklm"
>>> x[0::2] #0. 2. 4...
'acegikm'
>>> x[1::2] #1. 3. 5 ..
'bdfhjl'
>>> [i+j for i,j in zip(x[::2], x[1::2])] # zip makes (0,1),(2,3) ...
['ab', 'cd', 'ef', 'gh', 'ij', 'kl']

Same logic applies for lists too. String lenght doesn't matter, because you're simply adding two strings together.

Solution 2

Use an iterator.

List comprehension:

>>> si = iter(['abcd', 'e', 'fg', 'hijklmn', 'opq', 'r'])
>>> [c+next(si, '') for c in si]
['abcde', 'fghijklmn', 'opqr']
  • Very efficient for memory usage.
  • Exactly one traversal of s

Generator expression:

>>> si = iter(['abcd', 'e', 'fg', 'hijklmn', 'opq', 'r'])
>>> pair_iter = (c+next(si, '') for c in si)
>>> pair_iter # can be used in a for loop
<generator object at 0x4ccaa8>
>>> list(pair_iter) 
['abcde', 'fghijklmn', 'opqr']
  • use as an iterator

Using map, str.__add__, iter

>>> si = iter(['abcd', 'e', 'fg', 'hijklmn', 'opq', 'r'])
>>> map(str.__add__, si, si)
['abcde', 'fghijklmn', 'opqr']

next(iterator[, default]) is available starting in Python 2.6

Solution 3

just to be pythonic :-)

>>> x = ['a1sd','23df','aaa','ccc','rrrr', 'ssss', 'e', '']
>>> [x[i] + x[i+1] for i in range(0,len(x),2)]
['a1sd23df', 'aaaccc', 'rrrrssss', 'e']

in case the you want to be alarmed if the list length is odd you can try:

[x[i] + x[i+1] if not len(x) %2 else 'odd index' for i in range(0,len(x),2)]

Best of Luck

Solution 4

Without building temporary lists:

>>> import itertools
>>> s = 'abcdefgh'
>>> si = iter(s)
>>> [''.join(each) for each in itertools.izip(si, si)]
['ab', 'cd', 'ef', 'gh']

or:

>>> import itertools
>>> s = 'abcdefgh'
>>> si = iter(s)
>>> map(''.join, itertools.izip(si, si))
['ab', 'cd', 'ef', 'gh']

Solution 5

>>> lst =  ['abcd', 'e', 'fg', 'hijklmn', 'opq', 'r'] 
>>> print [lst[2*i]+lst[2*i+1] for i in range(len(lst)/2)]
['abcde', 'fghijklmn', 'opqr']
Share:
179,482

Related videos on Youtube

John
Author by

John

Updated on July 16, 2020

Comments

  • John
    John almost 4 years

    I know that a list can be joined to make one long string as in:

    x = ['a', 'b', 'c', 'd']
    print ''.join(x)
    

    Obviously this would output:

    'abcd'
    

    However, what I am trying to do is simply join the first and second strings in the list, then join the third and fourth and so on. In short, from the above example instead achieve an output of:

    ['ab', 'cd']
    

    Is there any simple way to do this? I should probably also mention that the lengths of the strings in the list will be unpredictable, as will the number of strings within the list, though the number of strings will always be even. So the original list could just as well be:

    ['abcd', 'e', 'fg', 'hijklmn', 'opq', 'r'] 
    
    • poke
      poke about 13 years
      “I should probably also mention that the lengths of the strings in the list will be unpredictable” – So does the length matter? I.e. do you just want to join every pair of list elements, or do you actually want to look at the content and join as long as the resulting element stays below some special length limit?
    • John
      John about 13 years
      simply join every pair, i just thought that having not knowing the number of pairs could be a problem
  • John
    John about 13 years
    Nice, but considering my code leaves me starting with the original list anyway, i think ill opt for utdmr's....thank you though
  • eyquem
    eyquem about 10 years
    There is no doubt that kevpie's answer is far better. In this one, x[:::2] creates an object, x[1::2] creates another object, these creations being probably based on calculation of indexes under the hood, and a call to a function with these two objects passed as arguments is necessary before being able to obtain the successive pairs of elements that must be concatenated. While in kevpie's answer, there's just the creation of one iterator and then the iteration skips from element to element of the untouched list without having to take care of the indexes, and that's far more pythonic.
  • eyquem
    eyquem about 10 years
    By far, the best answer. See my comment to utdemir's answer.
  • utdemir
    utdemir almost 10 years
    @eyquem, using itertools.islice instead of [], eliminates the intermediate objects. But since both answers works on same conditions and returns same, they are both right. And zip(i[::2], i[1::2]) looks so sweet to me, so, why not? :)
  • Kos
    Kos about 6 years
    This only works on sequences, while @kevpie's answer is more general and works on any iterable.