2

I currently have a list stored in a variable for example:

  • 01/01/2015
  • 13:22
  • Steak
  • 01/02/2015
  • 13:23
  • Fries
  • 01/03/2015
  • 13:23
  • Salad

I have a variable z that holds this information.

I want to join every 3 lines together so the output is date + time + order in one line. I tried the below but this puts 3 letters on each line rather than the 3 lines

threelines = range(0,len(z),3)
for num, line in enumerate(z):
    if num in threelines:
        print ' '.join(z[num:num+3])

Any help would be appreciated!

SB77
  • 87
  • 2
  • 8
  • 6
    What is `z`?... – Bhargav Rao Apr 29 '15 at 11:34
  • 2
    It would help if you include some actual input (say, the first 9 values of z?) and expected output (say, the three lines with the formatting you want) to the question. – musically_ut Apr 29 '15 at 11:35
  • 3
    Are you looking for [How do you split a list into evenly sized chunks in Python?](http://stackoverflow.com/q/312443/953482)? – Kevin Apr 29 '15 at 11:37
  • 2
    @BhargavRao: From the symptoms, I'd say that `z` is a string. But it would be good if SB77 could confirm that, preferably by adding some example data to the question. Otherwise, the question's in grave danger of being closed as unclear. – PM 2Ring Apr 29 '15 at 12:09
  • Hi Sorry I will update my question – SB77 Apr 29 '15 at 12:34
  • 1
    @SB77: Your update hasn't clarified the exact form of `z`. My guess is that your data is in a single string, with individual items separated by newlines, or perhaps by commas or some other separator character. Or it could be in a Python list of strings, but if that were the case your current code would do what you want (albeit in a rather strange way), as the answers below indicate. So to clarify this issue you should add code showing us what `z` _really_ looks like, similar to how all the answers have done. – PM 2Ring Apr 30 '15 at 06:58

4 Answers4

3

You do not need to use an index, and you can write very explicit code like:

lines_iter = iter(z.splitlines())  # If z is a file, lines_iter = z works
# itertools.izip() is usable, too, for a low memory footprint:
for date_time_order in zip(lines_iter, lines_iter, lines_iter):
    print " ".join(date_time_order)  # "<date> <time> <order>"

This has the advantage of giving you very legible variable names, and also of working even if z is an iterator (like a file): there is no need to know the number of lines in advance, and this method uses little memory.

The way it works comes from the specifics of how zip() works: it builds tuples of elements, by getting the next element of each of its arguments in turn. Thus, it first returns the first, second, and third element of lines_iter, etc.

Eric O. Lebigot
  • 91,433
  • 48
  • 218
  • 260
0

I dont know where you get z from but from your description it look like this:

# define z ......
z = ['date1', 'time1', 'Order1','date2', 'time2', 'Order2','date3', 'time3', 'Order3','date4', 'time4', 'Order4',]
# if z is a string with newlines (you mentioned lines...)
string_with_newlines ="date1\ntime1\nOrder1\ndate2\ntime2\nOrder2"
z = string_with_newlines.splitlines()
# z becomes ['date1', 'time1', 'Order1','date2', 'time2', 'Order2'] and that is a real list^

# make new list
l = []

# iterate over 3 items in z
for n in range(len(z)//3):
    # join the 3 item from z for this iteration and put them into the new list
    l.append(' '.join(z[n*3:n*3+3]))

print l

# print output
['date1 time1 Order1',
 'date2 time2 Order2',
 'date3 time3 Order3',
 'date4 time4 Order4']
yamm
  • 1,523
  • 1
  • 15
  • 25
0

Your code already works, but only if z is a list of strings, rather than a single string.

Original:

z = """Hello,
how
are
you?
I
am
fine.
Lovely
Weather."""

threelines = range(0,len(z),3)
for num, line in enumerate(z):
    if num in threelines:
        print ' '.join(z[num:num+3])

Result:

H e l
l o ,

 h o
...

Using a list instead:

z = """Hello,
how
are
you?
I
am
fine.
Lovely
Weather."""

z = z.split("\n")

threelines = range(0,len(z),3)
for num, line in enumerate(z):
    if num in threelines:
        print ' '.join(z[num:num+3])

Result:

Hello, how are
you? I am
fine. Lovely Weather.

Incidentally, your num in threelines check is a little inefficient for large inputs. I suggest using the chunking recipe from this post instead.

z = """Hello,
how
are
you?
I
am
fine.
Lovely
Weather."""

z = z.split("\n")

def chunks(l, n):
    """ Yield successive n-sized chunks from l.
    """
    for i in xrange(0, len(l), n):
        yield l[i:i+n]

for chunk in chunks(z, 3):
    print " ".join(chunk)
Community
  • 1
  • 1
Kevin
  • 74,910
  • 12
  • 133
  • 166
0

Actually, if z is a list of strings like

z = ['first line', 'second line', 'third line', ...]

your code should work. (and if it's not but it's a simple string you can make it a list of lines by using z.splitlines() or z.split() if they are separeted by spaces)

But it's particularly wasteful: you generate a list with all the indices that are multiple of 3, then enumerate the elements of your lists and if the index is in the list of indices multiple of 3 (a check you perform at every iteration!), you print the current element and the two after it.

You can directly generate chunks of 3 consecutive elements without using a condition inside a for loop. You can find multiple solutions here: How do you split a list into evenly sized chunks?

A simple one is:

z[i:i+3] for i in xrange(0, len(z), 3)
Community
  • 1
  • 1
LeartS
  • 2,866
  • 2
  • 25
  • 45