2

This is the input list

input_list = ['string','string','1','string','2','string','string','3','string','5']

This is the output required

    [['string', 'string', '1'], ['string', '2'], ['string', 'string', '3'], 
     ['string', '5']]

Basically you're grouping the list data string and (numeric data) into a list of lists, each list containing the first numeric data and previous string data encountered

A simple algorithm which can accomplish this

output_list = []
inner_list = []
for data in input_list:
    inner_list.append(data)
    if data.isdigit():
        output_list.append(inner_list)
        inner_list = []

print output_list

I was wondering if this could be made even simpler (accomplished in lesser number of lines)?

TigerhawkT3
  • 48,464
  • 6
  • 60
  • 97
wolfgang
  • 7,281
  • 12
  • 44
  • 72
  • 1
    you can save 1 line `inner_list.append(data)` (can be done unconditionally) and after the positive check `if data.isdigit():` you don't need the `else`. Elimination of two lines – Ronald Aug 01 '15 at 09:06
  • @Ronald Yes, edited :) I meant could this be accomplished in a much more simpler way without creating all these `inner_list` temp variables – wolfgang Aug 01 '15 at 09:10

4 Answers4

3

One liner with reduce. Do not use.

reduce(lambda n, e: n[:-1]+[n[-1]+[e]] + ([[]] if e.isdigit() else []), input_list, [[]])[:-1]
Maltysen
  • 1,868
  • 17
  • 17
3

You can first find the index of digit elements then use zip to create the desire slice indices and slice you list :

>>> ind=[0]+[i for i,j in enumerate(input_list,1) if j.isdigit()]
>>> [input_list[i:j] for i,j in zip(ind,ind[1:])]
[['string', 'string', '1'], ['string', '2'], ['string', 'string', '3'], ['string', '5']]
Mazdak
  • 105,000
  • 18
  • 159
  • 188
2

Even though this is a single line solution, it is not simpler, it's more complex:

input_list = ['string','string','1','string','2','string','string','3','string','5']
result = [s.split() for s in ' '.join([s+'\n' if s.isdigit() else s for s in input_list]).splitlines()]
print result

Output:

[['string', 'string', '1'], ['string', '2'], ['string', 'string', '3'], ['string', '5']]

Is this blob of complex code what you want?

(Note the bug: if one of the strings should already contain a \n. You could choose another character if you know for sure that it won't be in one of the strings).

mhawke
  • 84,695
  • 9
  • 117
  • 138
1

If you want a (slightly evil) reduce()-based version:

def reduce_string_prefix(cur, item):
    cur[-1].append(item)
    if item.isdigit():
        cur.append([])
    return cur

input_list = ['string', 'string', '1', 'string', '2', 'string', 'string', '3', 'string', '5']
output_list = reduce(reduce_string_prefix, input_list, [[]])[:-2]

I'm not so sure if this is actually easier to read, though ;-).

dhke
  • 15,008
  • 2
  • 39
  • 56