How can I iterate over a list of lists? - python

I'm trying to sort through a list of lists. How could I go about printing or iterating over the first and last elements in each list? non-working code below:
from numpy import *
xs=[[1.,2.,3.],[4.,5.,6.],[7.,8.,9.]]
for i in xs:
for j in xs[i]:
print(xs[1],xs[-1])
Traceback error if needed:
runfile('/Users/Alex/untitled9.py', wdir='/Users/Alex')
Traceback (most recent call last):
File "<ipython-input-14-8a28382c7f81>", line 1, in <module>
runfile('/Users/Alex/untitled9.py', wdir='/Users/Alex')
File "/anaconda/lib/python3.6/site-packages/spyder/utils/site/sitecustomize.py", line 880, in runfile
execfile(filename, namespace)
File "/anaconda/lib/python3.6/site-packages/spyder/utils/site/sitecustomize.py", line 102, in execfile
exec(compile(f.read(), filename, 'exec'), namespace)
File "/Users/Alex/untitled9.py", line 13, in <module>
for j in xs[i]:
TypeError: list indices must be integers or slices, not list

You've already been given the answer in the comments. But to understand why your code doesn't work in its current state, take a look at this:
>>> xs = [[1.,2.,3.], [4.,5.,6.], [7.,8.,9.]]
>>> for i in xs:
... print(i)
...
[1.0, 2.0, 3.0]
[4.0, 5.0, 6.0]
[7.0, 8.0, 9.0]
The for loop iterates over the elements, not the indices. The variable i is probably confusing here. Anyway, inside the loop, i will contain a sublist at each iteration. So xs[i] is an invalid operation here -- you may only provide integers as indices to a python list.
If you want to get the first and last element of each sublist, all you've got to do is print out i[0] and i[-1].
On a related note, you can iterate over the indices using the range function:
for i in range(len(xs)):
print(xs[i][0], xs[i][-1])
But this is not recommended, since it is more efficient to just iterate over the elements directly, especially for this use case.
You can also also use enumerate, if you need both:
for c, i in enumerate(xs):
print(i[0], xs[c][-1]) # both work here

In the code you have given:
for i in xs:
for j in xs[i]:
print(xs[1],xs[-1])
in the outer for loop, the variable i stores the inner arrays, so in the inner for loop, when you do xs[i], it gives an error. This is because you can only use integers as indices in an array (which makes sense, since you would want the the 0th or 1st or 2nd element, there is no such thing like [1,2,3]th element, which xs[i] in the code you have written essentially means).
Now, in order to simply iterate over the multidimensional array:
for i in xs:
for j in i:
print(j)
print("\n")
This will give:
[1.0, 2.0, 3.0]
[4.0, 5.0, 6.0]
[7.0, 8.0, 9.0]
If you want to print only the first and last items of the inner lists, this would do:
for i in xs:
print(i[0], i[-1], "\n")
Hope this helps

When you iterate over a list you get an item from each member of the list, and if that item is a list you can create a second loop to iterate over the item, like this:
for items in xs:
for elem in items:
# in here you get each element of the inner list
To get the first and last value though, You don't need that you can as answered previously:
for item in xs:
print(item[0], item[-1]
And if you are feeling a little funny you could even store those in your own list by using a comprehensive list, like so:
funny_list= [[item[0], item[-1]] for item in xs]

Try this:
li = []
for i in range(len(xs)):
li.append([xs[i][0],xs[i][-1]])
output: [[1.0, 3.0], [4.0, 6.0], [7.0, 9.0]]

Related

Element-wise appending of 2D lists? [duplicate]

This question already has answers here:
Python: merge nested lists
(4 answers)
Closed 9 months ago.
I want to concatenate 2D lists to the end of a list_log, as follows:
list_log = []
list1 = [[0.0], [1.7], [8.4], [20.1], [29.3], [41.8], [74.1], [61.9]]
list2 = [[1.0], [3.6], [13.5], [31.5], [50.3], [64.4], [93.3], [113.8]]
list_log.append(list1)
list_log.append(list2)
Desired result:
list_log = [[0.0, 1.0], [1.7, 3.6], [8.4, 13.5], [20.1, 31.5], [29.3, 50.3], [41.8, 64.4], [74.1, 93.3], [61.9, 113.8]]
Actual result: list_log = [[[0.0], [1.7], [8.4], [20.1], [29.3], [41.8], [74.1], [61.9]], [[1.0], [3.6], [13.5], [31.5], [50.3], [64.4], [93.3], [113.8]]]
I've also tried getting this result using list comprehension, as follows:
list_log2 = [[[i, j] for i in list1[c] for j in list2[c]] for c in range(8)]
But this gives the following result: list_log2 = [[[0.0, 1.0]], [[1.7, 3.6]], [[8.4, 13.5]], [[20.1, 31.5]], [[29.3, 50.3]], [[41.8, 64.4]], [[74.1, 93.3]], [[61.9, 113.8]]], so with too many brackets.
Also, the example above uses only two lists, but in reality I have thousands of these lists coming in one after the other, and which I need to append to the end of the list_log one-by-one. Because of this I'm reluctant to use list comprehension as shown above, because this basically re-generates the entire log_list2 each time I append a new list, which isn't very efficient. That's why I'm trying to make this happen with .append() instead, as adding one element to the end of a list is computationally much less intensive than re-creating the entire log each time.
So ideally I'd like to make this work with .append() (or similar stuff like .extend()), but I'm open to all suggestions. Thanks in advance!
You can do it using zip() and a list comprehension:
[[*i, *j] for i, j in zip(list1, list2)]
Output:
[[0.0, 1.0],
[1.7, 3.6],
[8.4, 13.5],
[20.1, 31.5],
[29.3, 50.3],
[41.8, 64.4],
[74.1, 93.3],
[61.9, 113.8]]
list1 = [[0.0], [1.7], [8.4], [20.1], [29.3], [41.8], [74.1], [61.9]]
list2 = [[1.0], [3.6], [13.5], [31.5], [50.3], [64.4], [93.3], [113.8]]
print([i+j for i,j in zip(list1,list2)])
>>>[[0.0, 1.0], [1.7, 3.6], [8.4, 13.5], [20.1, 31.5], [29.3, 50.3], [41.8, 64.4], [74.1, 93.3], [61.9, 113.8]]

Python print nth element from list of lists [duplicate]

This question already has answers here:
How to print column in python array?
(2 answers)
Closed 5 years ago.
I have the following list:
[[50.954818803035948, 55.49664787231189, 8007927.0, 0.0],
[50.630482185654436, 55.133473852776916, 8547795.0, 0.0],
[51.32738085400576, 55.118344981379266, 6600841.0, 0.0],
[49.425931642638567, 55.312890225131163, 7400096.0, 0.0],
[48.593467836476407, 55.073137270550006, 6001334.0, 0.0]]
I want to print the third element from every list. The desired result is:
8007927.0
8547795.0
6600841.0
7400096.0
6001334.0
I tried:
print data[:][2]
but it is not outputting the desired result.
Many way to do this. Here's a simple list way, without an explicit for loop.
tt = [[50.954818803035948, 55.49664787231189, 8007927.0, 0.0], [50.630482185654436, 55.133473852776916, 8547795.0, 0.0], [51.32738085400576, 55.118344981379266, 6600841.0, 0.0], [49.425931642638567, 55.312890225131163, 7400096.0, 0.0], [48.593467836476407, 55.073137270550006, 6001334.0, 0.0]]
print [x[2] for x in tt]
> [8007927.0, 8547795.0, 6600841.0, 7400096.0, 6001334.0]
And making is safe for potentially shorted lists
print [x[2] for x in tt if len(tt) > 3]
More sophisticated output (python 2.7), prints values as newline (\n) seperated
print '\n'.join([str(x[2]) for x in tt])
> 8007927.0
> 8547795.0
> 6600841.0
> 7400096.0
> 6001334.0
Try this:
for item in data:
if len(item) >= 3: # to prevent list out of bound exception.
print(int(item[2]))
map and list comprehensive have been given, I would like to provide two more ways, say d is your list:
With zip:
zip(*d)[2]
With numpy:
>>> import numpy
>>> nd = numpy.array(d)
>>> print(nd[:,2])
[ 8007927., 8547795., 6600841., 7400096., 6001334.]
Maybe you try a map function
In python 3:
list(map(lambda l: l[2], z))
In python 2:
map(lambda l: l[2], z)
In order to print the nth element of every list from a list of lists, you need to first access each list, and then access the nth element in that list.
In practice, it would look something like this
def print_nth_element(listset, n):
for listitem in listset:
print(int(listitem[n])) # Since you want them to be ints
Which could then be called in the form print_nth_element(data, 2) for your case.
The reason your data[:][2] is not yielding correct results is because data[:] returns the entire list of lists as it is, and then executing getting the 3rd element of that same list is just getting the thirst element of the original list. So data[:][2] is practically equivalent to data[2].

Equal elements in list of lists. Delete one

I have a list of lists
list = [[-2.0, 5.0], [-1.0, -3.0], [1.0, 3.0], [2.0, -5.0]]
What I want to do is delete one the elements of same value should I divide first element with second. For example [-2.0, 5.0] = -2/5 and [2.0, -5.0] = -2/5. I want to delete either [-2.0, 5.0] or [2.0, -5.0] since they produce the same value.
Any ideas?
Can i try like this:
Tuple could be a dictionary key, so I converted the list into tuple after changing to abs
value of the list element and keeping the original list as the values.
>>> lis
[[-2.0, 5.0], [-1.0, -3.0], [1.0, 3.0], [2.0, -5.0]]
>>> dict([(tuple([abs(x[0]), abs(x[1])]), x) for x in lis]).values()
[[2.0, -5.0], [1.0, 3.0]]
>>>
Assuming all your values are all floats (so you can always use float division) you can do the following:
my_list = [[-2.0, 5.0], [-1.0, -3.0], [1.0, 3.0], [2.0, -5.0]]
values_seen = []
new_list = []
for x,y in my_list:
if x/y in values_seen:
continue
else:
values_seen.append(x/y)
new_list.append([x,y])
Now the list you want will be stored as new_list. Note that you should avoid writing a value to the keyword list as you have above.
*Clarification, I am assuming that if you have any more than 2 values that return the same ratio (for example [[1,3],[2,6],[3,9]]) you will want to keep only one of these.
If you want to eliminate all equivalent fractions (meaning [-2.0, 5.0] and [4.0, -10.0] are considered equivalent), then the following code would work.
seen = set()
for numerator, denominator in lst:
quotient = numerator / denominator
if quotient not in seen:
seen.add(quotient)
yield numerator, denominator
Otherwise, if you want the final list to contain both [-2.0, 5.0] and [4.0, -10.0]:
seen = set()
for numerator, denominator in lst:
value = (abs(numerator), abs(denominator), sign(numerator)*sign(denominator))
if value not in seen:
seen.add(value)
yield numerator, denominator
If you're writing this in Python, a language that lacks a sign function, you'll either need to use math.copysign or (numerator > 0) ^ (denominator > 0) where ^ is the xor operator.
This code assumes both numerator and denominator are nonzero.
If you really are keeping a list of numerator-denominator number pairs, consider storing the pairs as immutable tuples or better yet, as Python fractions.
I would first get a unique set of ratios using set:
In [1]: lst = [[-2.0, 5.0], [-1.0, -3.0], [1.0, 3.0], [2.0, -5.0]]
In [2]: rs = list(set([ l[0]/l[1] for l in lst]))
And then just filter out the first occurance of the ratios:
In [3]: [ filter(lambda m: m[0]/m[1] == r , lst )[0] for r in rs ]
Out[3]: [[-2.0, 5.0], [-1.0, -3.0]]
In [4]:
Quick and dirty way, since keys in a dictionary are unique.
{num/denom : [num, denom] for (num, denom) in lst}.values()
In general, comparing floats using == is unreliable, it's normally better to check if they're within a tolerance. e.g.
abs(x-y) < tolerance
a more robust way would might look like the following. An else attached to a for loop just means do this unless you exited the loop early. It's quite handy. This version, however, is quadratic rather than linear time.
div = lambda x,y : x/y
unique = []
for j in range(len(lst)):
for i in range(j):
if abs( div(*lst[i])-div(*lst[j]) ) < tolerance:
break
else
unique.append(lst[j])
unique

Convert elements within an array into floats in python

Hi I am quite new to python and what I want to do is simple but I just can't seem to get around it.
I have a simple array as shown below:
A1 = [('1.000000', '4.000000'), ('2.000000', '5.000000'), ('3.000000', '6.000000'), ('1.000000', '4.000000'), ('2.000000', '5.000000'), ('3.000000', '6.000000')]
I want to change all elements within the array into floats so I can do calculations on them (such as sum etc.). The end results should look something like this:
A2 = [(1.000000, 4.000000), (2.000000, 5.000000), (3.000000, 6.000000), (1.000000, 4.000000), (2.000000, 5.000000), (3.000000, 6.000000)]
I have tried the following:
A2 = [float(i) for i in A1]
however I get the error:
TypeError: float() argument must be a string or a number
Could anyone point me towards a solution.
Thanks in advance
Here's one pretty simple way:
>>> [map(float, x) for x in A1]
[[1.0, 4.0], [2.0, 5.0], [3.0, 6.0], [1.0, 4.0], [2.0, 5.0], [3.0, 6.0]]
I like it's because it's short (some would say terse) and since using map() makes it not hardcode or be explicit about the expected format of each x, it just says that it assumes A1 to be a list of sequences.
I have no idea how this compares performance-wise to other solutions (such as the more explicit [(float(x), float(y) for (x, y) in A1] seen below).
Each element of A1 is a tuple ('1.000000', '4.000000'). You will have to convert each item of the tuple:
A2 = [(float(i), float(j)) for (i, j) in A1]
You need to iterate over the inner tuples as well.
A2 = [tuple(float(s) for s in i) for i in A1]

Building multiple lists from single list with multiple lists within

def main():
my_list = [[float(i) for i in line.split(',')] for line in open("Alpha.txt")]
print(my_list)
for elem in my_list:
listA=[]
listA = elem
print(listA)
main()
this code prints out the correct data of which im looking for, however i need to set each print from the for loop into a object. Any help as to how i would go about doing that?
[1.2, 4.3, 7.0, 0.0]
[3.0, 5.0, 8.2, 9.0]
[4.0, 3.0, 8.0, 5.6]
[8.0, 4.0, 3.0, 7.4]
What you're thinking of/trying to do is to dynamically name variables.
Don't.
Either leave your data in the list and access it via index
my_list[0] #what you were trying to assign to 'a'
my_list[0][0] #the first element in that sub-list
Or, if you have meaningful identifiers that you want to assign to each, you can use a dict to assign "keys" to "values".
d = {}
for sublist, meaningful_identifier in zip(my_list, my_meaningful_identifiers):
d[meaningful_identifier] = sublist
Either way, leverage python data structures to do what they were supposed to do.
This is not a good idea, let me warn you, and you should never use this in production code (it is prone to code injection), and screws up your global namespace, but it does what you asked.
You would use exec() for this, which is a function that dynamically executes statements.
def main():
my_list = [[float(i) for i in line.split(',')] for line in open("Alpha.txt", "r")]
print(my_list)
for elem in my_list:
exec "%s = %s" % ("abcdefghijklmnopqrstuvwxyz"[my_list.index(elem)], elem) in globals()
main()
Now, your global namespace is filled with variables a, b, c, etc. corresponding to the elements.
It is also prone to exceptions, if you have more than 26 elements, you will get an IndexError, although you could work around that.
Try:
myList = [map(float, line.split(',')) for line in open ("Alpha.txt")]
Now you can get each line in a different variable if you want:
a = myList[0]
b = myList[1]
and so on. But since you have a list, it's better to use it and access elements using indices. Are you sure have a correct understanding of arrays?
As the other answers point out, it is dangerous and doesn't make sense to dynamically create variables.

Categories