0

I have a list (from CSV) with the following information structure:

Item 1
NUMBER Random ID
Item 2
NUMBER Random ID
Item 3
Item 4
Item 5
NUMBER Random ID

And I would like to create a new list (CSV) that looks like this:

Item 1 NUMBER Random ID
Item 2 NUMBER Random ID
Item 5 NUMBER Random ID

So I would like to create a string from Item 1,2,3... and the line under it, if the next line doesn't contain the string NUMBER.

I can read the CSV and use it as a list, however I don't know how the track the lines. My first idea is to create a list of dicts where every dict contains the index number of the line and the content, and then I can loop through the list_with_dicts and check the next line from the original list.

raw_list = [] 
num = 0
list_with_dicts = []
for x in raw_list:
    
    num2 = num + 1
    dict1 = {}
    dict1['index'] = num2
    dict1['çontent'] = x 
    list_with_dicts.append(dict1)

for d in list_with_dicts:
    
    number_of_next_line = d['index'] + 1    
    
    if "NUMBER" in raw_list[number_of_next_line]:
        new_string = "%s %s" % (d[content], raw_list[number_of_next_line])
    else:
        print("String without number")

However I'm not sure that it's the easiest and best way to do it. Is there a simpler workaround?

3
  • Please lable the columns you get from the CSV. Commented Sep 19, 2016 at 22:05
  • As you have working code, this might be better suited for CodeReview Commented Sep 19, 2016 at 22:07
  • @Dan There is no columns. It contains just one single column. Commented Sep 19, 2016 at 22:07

6 Answers 6

2

Fun question!

raw_list = ["Item 1",
            "NUMBER Random ID1",
            "Item 2",
            "NUMBER Random ID2",
            "Item 3",
            "Item 4",
            "Item 5",
            "NUMBER Random ID5"]

clean_list = [raw_list[i]+" "+raw_list[i+1] for i in range(0,len(raw_list),2) if "Item" not in raw_list[i+1]]
print clean_list

Output:

['Item 1 NUMBER Random ID1', 'Item 2 NUMBER Random ID2', 'Item 5 NUMBER Random ID5']

You can also use zip to make it shorter but maybe less readable:

clean_list1 = [i1+" "+i2 for i1,i2 in zip(raw_list[::2],raw_list[1::2]) if "Item" not in i2]
print clean_list1
Sign up to request clarification or add additional context in comments.

Comments

2

Here's a slightly different take on the problem - search for lines that contain the string NUMBER and then join that line with the previous one. This produces simpler code:

l = ['Item 1', 'NUMBER Random ID', 'Item 2', 'NUMBER Random ID', 'Item 3', 'Item 4', 'Item 5', 'NUMBER Random ID']

result = []
for i, s in enumerate(l[1:], 1):
    if 'NUMBER' in s:
       result.append('{} {}'.format(l[i-1], s))

Or as a list comprehension:

result = ['{} {}'.format(l[i-1], s) for i,s in enumerate(l[1:], 1) if 'NUMBER' in s]

It's unclear what is expected as output - you mention CSV which implies that the output list should contain individual fields, in which case the result should be a list of lists. Something like this:

result = [[l[i-1], s] for i,s in enumerate(l[1:], 1) if 'NUMBER' in s]

which would create this list of lists:

[['Item 1', 'NUMBER Random ID'],
 ['Item 2', 'NUMBER Random ID'],
 ['Item 5', 'NUMBER Random ID']]

which can easily be saved to a CSV file with the csv module:

import csv

with open('result.csv', 'w') as f:
    csv.writer(f).writerows(result)

Comments

1

With list comprehension:

result = ["%s %s" % (x,raw_list[i+1]) for i, x in enumerate(raw_list) 
                if i < len(raw_list)-1 and 'NUMBER' in raw_list[i+1]]

Comments

1

With enumerate(<list>) you can iterate on indices and elements, so you can easily check the next element:

result = []
for i, val in enumerate(lst):
    if i == len(lst) - 1:
        break # to avoid IndexError
    if lst[i + 1][:3] == 'NUM':
        result.append('%s %s' % (val, lst[i + 1])

Version with functional programming:

result = \
    list(
        map(
            lambda i: 
                 '%s %s' % (lst[i - 1], lst[i]),
            filter(
                lambda i:
                    lst[i][:3] == 'NUM',
                range(1, len(lst))
            )
        )
    )

Comments

0
new_list=[]
i=0
while i < len(raw_list)-1:
    if raw_list[i+1][:len("NUMBER")] == "NUMBER":
        new_list.append("%s %s" % (raw_list[i], raw_list[i+1]))
        i=i+2
    else:
        i=i+1

Comments

0
result = []
i, l = 0, len(raw_input)
while i < l:
  if 'item' in raw_input[i]:
    result.append(raw_input[i])
  else:
    result[-1] += raw_input[i]
  i += 1
return filter(lambda x: 'random' in x.lower(), result)

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.