Print sublists in python - python

I am trying to print a list of lists in python like so:
for location in latLongList:
print ' '.join(map(str, location))
This prints out:
40.0349216312 -75.1900864349 Paved 4 0.156150432289
39.9531308619 -75.1629612614 Paved 3 0.170932927052
39.9610355788 -75.1725011285 Paved 0.17296824247
39.9788367755 -75.2123945669 Paved 0.196740550111
39.9467944475 -75.2092212039 Paved 33 0.210834020854
39.94626513 -75.2089212417 Paved 5 0.210899309368
39.9373184367 -75.2341880089 Grass 0.236747322815
39.9413269464 -75.2383849209 0.238056333485
This works fine but I wanted to exclude the last number in each line (which is the last number in each sublist). I also wanted to be able to allow the user to specify the number of lines to be printed. They input that number through the command line and it is stored in a variable called sizeOfList. Would there be an easy way to do this in python? Any help would be greatly appreciated!

You could use the built-in function enumerate to get the index of each location in latLongList, and then print only locations whose index is less than the number desired by the user (sizeOfList). Then, in order to exclude the last item in each sublist (each location), you could take a slice of the sublist up to, but not including, the last item (which is at index -1).
for i, location in enumerate(latLongList):
if i < sizeOfList:
print ' '.join(map(str, location[:-1]))
#Hackaholic introduced an improvement to this method, which makes the code more concise and potentially much faster (due to iteration over fewer locations):
for location in latLongList[:sizeOfList]:
print ' '.join(map(str, location[:-1]))
Here, only the items up to the number desired by the user (sizeOfList) are taken from latLongList. There is no longer a need for enumerate.

You could do something like this:
# this import needs to be first
from __future__ import print_function
for location in latLongList[:sizeOfList]:
print(*location[:-1])
The __future__ import makes print a function, so you can do print(*foo). That's like print(foo[0], foo[1], ...).

First, to print everything but the last element, you slice the list to include everything but its last element: location[:-1]. (Slicing is explained in the tutorial in Using Python as a Calculator; for full details see Sequence Types in the library reference.)
Then, to stop after a certain number of lines, you slice the list of lines: latLongList[:sizeOfList].
So:
for location in latLongList[:sizeOfList]:
print ' '.join(map(str, location[:-1]))
If the list weren't actually a list, but an iterator (or if you were writing generic code that needed to work with both), or if you were worried about the memory waste in making a copy of part of the list (say because you want the first 200 million lines), you could use islice, which solves both of those problems:
from itertools import islice
for location in islice(latLongList, sizeOfList):
print ' '.join(map(str, location[:-1]))

Better to try like this:
for location in latLongList[:sizeOfList]:
print ' '.join(map(str, location[:-1]))

This should solve both problems:
print '\n'.join('{} {} {}'.format(*location) for location in latLongList[:sizeOfList])
This solution is pretty Pythonic. Using str.format() eliminates the need to convert everything to strings by using map(str, ) (str.format() does this automatically for you). Additionally, there is no need to slice the sublist for each location to eliminate the last element, as str.join() ignores the rest of the list automatically. Lastly, it reduces the number of calls to print from sizeOfList times to once. And the str.join() operation is fast because it is joining an iterator instead of a list.
Enjoy!

Related

Identify first or last item returned by iteritem in python 2.7

I have a python 2.7 script that is generating Verilog code. I need to create a comma-separated list of the keys in a dictionary. For example, if the keys in the dictionary are 'A', 'B', and 'C', I need to be able to print to the generated file 'A, B, C', or 'B, A, C', or whatever order the keys come out (I don't care about the order). The interesting part is that I can't have a comma at the end, so I need to identify either the first item that is being returned or the last in order to handle one of them differently.
Is there a clean, 'Pythonic' way to identify the first or last item being returned by iteritems?
Unlike Looping over a dictionary without first and last element, I do want all of the items and I don't care about the returned order. Using the method in the answers to that question to convert the dictionary to a list, then explicitly iterating through the items and handling the first or last items differently seems like a lot of contortion.
The work-around I am currently using feels very 'C-ish': I set a 'first_item' variable to True before the iteritems, then test for it inside the loop, do something different for the first item and then change it to False. This works, but isn't a particularly elegant solution:
# Generate the group enum declaration
fp.write('enum {')
first_item = True
for k,v in c.iteritems():
if first_item:
first_item = False
fp.write(k)
else:
fp.write(', ' + k)
fp.write('} group;\n')
And the only hack I could come up for differentiating the last item is even uglier - set a variable to len(dictionary), then decrement it each pass of the iteritems loop and do something different when it gets to 1.
Uglier still, IMO, is adding the ', ' + k to a string a for every key, then removing the first two characters.
Any suggestions for how to do this more cleanly than the work-around shown above?
You can avoid the whole problem by using join. Also, since you don't need the values, you can iterate over the keys only.
fp.write('enum {')
fp.write(', '.join(c.iterkeys()))
fp.write('} group;\n')

Reduce a list in a specific way

I have a list of strings which looks like this:
['(num1, num2):1', '(num3, num4):1', '(num5, num6):1', '(num7, num8):1']
What I try to achieve is to reduce this list and combine every two elements and I want to do this until there is only one big string element left.
So the intermediate list would look like this:
['((num1, num2):1,(num3, num4):1)', '((num5, num6):1,(num7, num8):1)']
The complicated thing is (as you can see in the intermediate list), that two strings need to be wrapped in paranthesis. So for the above mentioned starting point the final result should look like this:
(((num_1,num_2):1,(num_3,num_4):1),((num_5,num_6):1,(num_7,num_8):1))
Of course this should work in a generic way also for 8, 16 or more string elements in the starting list. Or to be more precise it should work for an=2(n+1).
Just to be very specific how the result should look with 8 elements:
'((((num_1,num_2):1,(num_3,num_4):1),((num_5,num_6):1,(num_7,num_8):1)),(((num_9,num_10):1,(num_11,num_12):1),((num_13,num_14):1,(num_15,num_16):1)))'
I already solved the problem using nested for loops but I thought there should be a more functional or short-cut solution.
I also found this solution on stackoverflow:
import itertools as it
l = [map( ",".join ,list(it.combinations(my_list, l))) for l in range(1,len(my_list)+1)]
Although, the join isn't bad, I still need the paranthesis. I tried to use:
"{},{}".format
instead of .join but this seems to be to easy to work :).
I also thought to use reduce but obviously this is not the right function. Maybe one can implement an own reduce function or so?
I hope some advanced pythonics can help me.
Sounds like a job for the zip clustering idiom: zip(*[iter(x)]*n) where you want to break iterable x into size n chunks. This will discard "leftover" elements that don't make up a full chunk. For x=[1, 2, 3], n=2 this would yield (1, 2)
def reducer(l):
while len(l) > 1:
l = ['({},{})'.format(x, y) for x, y in zip(*[iter(l)]*2)]
return l
reducer(['(num1, num2):1', '(num3, num4):1', '(num5, num6):1', '(num7, num8):1'])
# ['(((num1, num2):1,(num3, num4):1),((num5, num6):1,(num7, num8):1))']
This is an explanation of what is happening in zip(*[iter(l)]*2)
[iter(l)*2] This creates an list of length 2 with two times the same iterable element or to be more precise with two references to the same iter-object.
zip(*...) does the extracting. It pulls:
Loop
the first element from the first reference of the iter-object
the second element from the second reference of the iter-object
Loop
the third element from the first reference of the iter-object
the fourth element from the second reference of the iter object
Loop
the fifth element from the first reference of the iter-object
the sixth element from the second reference of the iter-object
and so on...
Therefore we have the extracted elements available in the for-loop and can use them as x and y for further processing.
This is really handy.
I also want to point to this thread since it helped me to understand the concept.

How to print values in a list on separate lines? Must use a for statement.

I need to use a for statement in order to print each value of a list on separate lines. When using the for statement it prints the entire list on one line. Additionally when trying to print just the values in the list on the same line it appears with double brackets instead of single.
Numbers=range(5,25,4)
NumberSequence=[]
NumberSequence.append(Numbers)
print NumberSequence
for elem in NumberSequence:
print elem
NumberSequence2=[]
Numbers2=range(26,0,-7)
NumberSequence2.append(Numbers2)
print NumberSequence2
for digits in NumberSequence2:
print digits
That is because you made a list and then put it inside of another list. If I understand you correctly, you want to print each individual number on a separate line. This can be done with:
Numbers = range(5,24,4)
for elem in Numbers:
print elem
Also, as #roganjosh mentioned, you seem to be using Python 2 which is rather old, slower than Python 3, and it's days of being supported are numbered. I highly recommend you make the switch to python 3 :)

Python 3 Error Missunderstanding (IndexError)

Here's my code
def abc(l,z):
L=[]
länge= len(L)
for x in range(0, länge+1):
L[x]+z
print(L)
abc(["1","2","3"],"-")
I want the program to output "1-2-3"
l in abc(l,z) should be a List out of Strings which combines "l" and "z" to a single String.
I'm getting an Index Error: list index out of range.
There are a couple of issues here.
First, range(0, länge+1) will stop at länge but your list only has indexes from 0 tolänge - 1, so that's one source for an IndexError.
Second, L[x]+z will give you another IndexError because L is empty but you try to access L[0] (and in the next iteration, where you don't get because of the error, L[1], L[2], and so on).
Third, even without an IndexError the statement L[x]+z will do nothing. You compute the value of L[x]+z but then you don't assign any variable to it, so it is immediately lost.
Fourth, in order to print your final result, put the call to print after the for loop, not inside. Consider using return instead of print if you actually want to do something with the result the function produces (make sure to educate yourself on the difference between print and return).
Fifth, you want to build a string, so the usage of the list L does not make much sense. Start with an empty string and add the current item from l and z to it in the loop body (coupled with a re-assignment in order to not lose the freshly computed value).
Lastly, there's no point in using range here. You can iterate over values in a list direclty by simply writing for x in l:.
That should give you enough to work with and fix your code for now.
(If you don't care why your function does not work and this is not an exercise, simply use str.join as suggested in the comments.)

Python: removing specific lines from an object

I have a bit of a weird question here.
I am using iperf to test performance between a device and a server. I get the results of this test over SSH, which I then want to parse into values using a parser that has already been made. However, there are several lines at the top of the results (which I read into an object of lines) that I don't want to go into the parser. I know exactly how many lines I need to remove from the top each time though. Is there any way to drop specific entries out of a list? Something like this in psuedo-python
print list
["line1","line2","line3","line4"]
list = list.drop([0 - 1])
print list
["line3","line4"]
If anyone knows anything I could use I would really appreciate you helping me out. The only thing I can think of is writing a loop to iterate through and make a new list only putting in what I need. Anyway, thanlks!
Michael
Slices:
l = ["line1","line2","line3","line4"]
print l[2:] # print from 2nd element (including) onwards
["line3","line4"]
Slices syntax is [from(included):to(excluded):step]. Each part is optional. So you can write [:] to get the whole list (or any iterable for that matter -- string and tuple as an example from the built-ins). You can also use negative indexes, so [:-2] means from beginning to the second last element. You can also step backwards, [::-1] means get all, but in reversed order.
Also, don't use list as a variable name. It overrides the built-in list class.
This is what the slice operator is for:
>>> before = [1,2,3,4]
>>> after = before[2:]
>>> print after
[3, 4]
In this instance, before[2:] says 'give me the elements of the list before, starting at element 2 and all the way until the end.'
(also -- don't use reserved words like list or dict as variable names -- doing that can lead to confusing bugs)
You can use slices for that:
>>> l = ["line1","line2","line3","line4"] # don't use "list" as variable name, it's a built-in.
>>> print l[2:] # to discard items up to some point, specify a starting index and no stop point.
['line3', 'line4']
>>> print l[:1] + l[3:] # to drop items "in the middle", join two slices.
['line1', 'line4']
why not use a basic list slice? something like:
list = list[3:] #everything from the 3 position to the end
You want del for that
del list[:2]
You can use "del" statment to remove specific entries :
del(list[0]) # remove entry 0
del(list[0:2]) # remove entries 0 and 1

Categories