Adding a constant tuple value to a list of tuples - python

I have a list of tuples (each tuple item is a pair of integers) and I would like to add a constant value to each tuple in the list.
For example
[(x0,y0),(x1,y1),...] -> [(x0+xk,y0+yk),(x1+xk,y1+yk)....]
xk,yk are constants
How do I do this
Thanks

Use numpy, e.g.,
>>> import numpy as np
>>> a = np.array([[1,2],[2,3]])
>>> print a
[[1 2]
[2 3]]
>>> print a + 2
[[3 4]
[4 5]]

>>>> l = [(1,2), (3,4)]
>>>> for i, e in enumerate(l):
.... l[i] = (e[0]+xk, e[1]+yk)
As always, untested. ;-)
If you don't need to do it in place, it's even simpler
>>>> l = [(e[0]+xk, e[1]+yk) for e in l]

You can't add a constant to a tuple because tuples are immutable.
You can however create a new tuple from the old one by incrementing it's values. See jae's answer for the basics of how to do this.
You should note however that you will be creating a lot of new tuples in this loop and this may not be a very efficient way of handling this. You should investigate numpy (as suggested by nikow) or perhaps using lists or coordinate objects instead of tuples.

an example to add things to tuple
>>> a=(1,2)
>>> a+=(1,)
>>> a
(1, 2, 1)
you can adapt it to your requirement

Solution:
l = [(i[0]+k[0], i[1]+k[1]) for i in l]
Test code:
l = [(1,2), (3,4)]
k = (10, 100)
l = [(i[0]+k[0], i[1]+k[1]) for i in l]
assert l == [(11, 102), (13, 104)]

Related

Indexing a 2D List with another List

If I have a list such as:
lst = [[1,2,3], [4,5,6], [7,8,9]]
and another list which contains a [row, column] index for an element in the list, so for example:
index = [2, 1]
Obviously I can get the element at index with:
lst[index[0]][index[1]]
However, I find that this syntax is quite clunky and doesn't sit well in a big block of code. It would also become worse with a higher dimensional list.
My question: is there an easier way to do this index?
It would seem that something like:
lst[index]
would be more readable but this isn't how Python works so isn't an option.
Since you're working with a 2D-list, it might be a good idea to use numpy. You'll then simply need to define index as a tuple. Index 3 would be out of range, though:
>>> import numpy as np
>>> a = np.array([[1,2,3], [4,5,6], [7,8,9]])
>>> index = (1, 2)
>>> a[index]
6
The method you're looking for is called Array#dig in Ruby:
[[1,2,3], [4,5,6], [7,8,9]].dig(1, 2)
# 6
but I couldn't find any plain Python equivalent.
You could just create a simple function that iterates over the index. For every element in index just fetch item from object and assign that as a new object. Once you have iterated over the whole index return current object. As #EricDuminil noted it works with dicts and all other objects that support __getitem__:
def index(obj, idx):
for i in idx:
obj = obj[i]
return obj
LST = [[1,2,3], [4,[5],6], [{'foo': {'bar': 'foobar'}},8,9]]
INDEXES = [[2, 2], [1, 1, 0], [2, 0, 'foo', 'bar']]
for i in INDEXES:
print('{0} -> {1}'.format(i, index(LST, i)))
Output:
[2, 2] -> 9
[1, 1, 0] -> 5
[2, 0, 'foo', 'bar'] -> foobar
The method you used is probably the simplest way, but for better readability you could go for something like
i = index[0]
j = index[1]
x = lst[i][j]
One way or another, you need to split your index list into the 2 values. If you want to declutter your main block of code, you can write a function to handle this, but that would hardly be "easier".
EDIT: As suggested below, tuple unpacking is an even better option
i, j = index
x = lst[i][j]

Extracting first elements from a list of tuples using list comprehension [duplicate]

This question already has answers here:
How to get first element in a list of tuples?
(17 answers)
Closed 2 years ago.
I have a list of tuples of which I want to extract the first element of each tuple to another list.
I had a list of tuples called lst and tried to extract the elements to a list called lst2 and what I got was:
>>> lst = [(1, 2), (3, 4), (5, 6)]
>>> lst2 = []
>>> [lst2[i] = lst[i][0] for i in range(len(lst))]
File "<stdin>", line 1
[lst2[i] = lst[i][0] for i in range(len(list))]
^
SyntaxError: invalid syntax
The desired output is [1, 3, 5].
Can you help figure out what's wrong with this syntax?
Using lst and lst2 as the variable names as others have noted list is a bad choice.
You don't need the index. Using the index is often considered bad form.
lst2 = [ pair[0] for pair in lst]
If you really, really need the index, for some math or something.
lst2 = [ lst[i][0] for (i, pair) in enumerate(lst)]
If you need to manipulate 2 dimensional matrices of numbers, you might want to learn about numpy and look at numpy.matrix and numpy.array.
Inside the list comprehension, only expression can come. list2[i] = list[i][0] is an assignment statement.
And, you don't need to use indexes to access items. Just iterate the list.
>>> lst = [ (1,2), (3,4), (5,6)]
>>> lst2 = [x[0] for x in lst]
>>> lst2
[1, 3, 5]
BTW, don't use list as a variable name. It shadows builtin type/function list.
You can't set a variable using the equals operator while looping through a list in one line. You could simply do it like this:
list = [ (1,2), (3,4), (5,6)]
list2 = []
[list2.append(list[i]) for i in range(len(list))]
Another way to do this is with zip():
>>> lst = [(1,2), (3,4), (5,6)]
>>> zip(*lst)
[(1, 3, 5), (2, 4, 6)]
>>> zip(*lst)[0]
(1, 3, 5)
>>> list(zip(*lst)[0])
[1, 3, 5]
However, it is a little wasteful when you only need the one list.

Flatten a list in python [duplicate]

This question already has answers here:
How do I make a flat list out of a list of lists?
(34 answers)
Closed 6 months ago.
I have a list like this:
[[(video1,4)], [(video2,5),(video3,8)], [(video1,5)], [(video5, 7), (video6,9)]...]
each item in this list may contain a single data pair, or a tuple, I want to change this list into
[(video1,4),(video2,5),(video3,8),(video1,5),(video5,7),(video6,9)...]
then do this:
for item in list:
reqs = reqs + item[1]
b.append(item[0])
c = set(b)
I don't know how to change the list structure, or how to do the same calculation based on the original list?
There is a very simple way of doing this with list comprehensions. This example has been documented in the python documentation here
>>> # flatten a list using a listcomp with two 'for'
>>> vec = [[1,2,3], [4,5,6], [7,8,9]]
>>> [num for elem in vec for num in elem]
[1, 2, 3, 4, 5, 6, 7, 8, 9]
Here is the solution that you would want to implement. As per your example, this is the simplest solution
In [59]: your_list = [[('video1',4)], [('video2',5),('video3',8)], [('video1',5)], [('video5', 7), ('video6',9)]]
In [60]: improved_list = [num for elem in your_list for num in elem]
In [61]: improved_list
Out[61]:
[('video1', 4),
('video2', 5),
('video3', 8),
('video1', 5),
('video5', 7),
('video6', 9)]
If this list is singly-nested (list of lists) you can do this, which I use a lot:
flat_list = sum(list_of_lists, [])
This works due to the fact that sum simply adds up the lists, and adding up lists works in python as expected :)
Note: This is inefficient and some say unreadable.
If you just want to flatten the list, just use itertools.chain.from_iterable: http://docs.python.org/library/itertools.html#itertools.chain.from_iterable
To flatten one level, you can use itertools.chain.from_iterable():
flattened_list = itertools.chain.from_iterable(my_list)
Here's another one (no libraries):
def plus(a,b): return a + b
reduce(plus, your_list)
Try this:
from itertools import chain
c = set()
reqs = 0
for vid, number in chain(*your_list):
c.add(vid)
reqs += number
Also see related post Flattening a shallow list in Python.
There should be negligible performance increase from using chain.from_iterable(list) rather than chain(*list), but it's true that the former looks cleaner.
to extract all tuples from a data structure ...
def get_tups(y):
z = []
if y:
for x in y:
if isinstance(x, tuple):
z.append(x)
else:
z.extend(get_tups(x))
return z
maybe ...

Multiple counters in a single for loop : Python

Is it possible in Python to run multiple counters in a single for loop as in C/C++?
I would want something like -- for i,j in x,range(0,len(x)): I know Python interprets this differently and why, but how would I run two loop counters concurrently in a single for loop?
You want zip in general, which combines two iterators, as #S.Mark says. But in this case enumerate does exactly what you need, which means you don't have to use range directly:
for j, i in enumerate(x):
Note that this gives the index of x first, so I've reversed j, i.
You might want to use zip
for i,j in zip(x,range(0,len(x))):
Example,
>>> x = [1, 2, 3]
>>> y = [4, 5, 6]
>>> zipped = zip(x, y)
>>> print zipped
[(1, 4), (2, 5), (3, 6)]
>>> for a,b in zipped:
... print a,b
...
1 4
2 5
3 6
>>>
Note: The correct answer for this question is enumerate as other mentioned, zip is general option to have multiple items in a single loop
for i,j in enumerate(x)

Is there a better way to iterate over two lists, getting one element from each list for each iteration? [duplicate]

This question already has answers here:
How do I iterate through two lists in parallel?
(8 answers)
Closed 5 years ago.
I have a list of Latitudes and one of Longitudes and need to iterate over the latitude and longitude pairs.
Is it better to:
A. Assume that the lists are of equal lengths:
for i in range(len(Latitudes)):
Lat,Long=(Latitudes[i],Longitudes[i])
B. Or:
for Lat,Long in [(x,y) for x in Latitudes for y in Longitudes]:
(Note that B is incorrect. This gives me all the pairs, equivalent to itertools.product())
Any thoughts on the relative merits of each, or which is more pythonic?
This is as pythonic as you can get:
for lat, long in zip(Latitudes, Longitudes):
print(lat, long)
Another way to do this would be to by using map.
>>> a
[1, 2, 3]
>>> b
[4, 5, 6]
>>> for i,j in map(None,a,b):
... print i,j
...
1 4
2 5
3 6
One difference in using map compared to zip is, with zip the length of new list is
same as the length of shortest list.
For example:
>>> a
[1, 2, 3, 9]
>>> b
[4, 5, 6]
>>> for i,j in zip(a,b):
... print i,j
...
1 4
2 5
3 6
Using map on same data:
>>> for i,j in map(None,a,b):
... print i,j
...
1 4
2 5
3 6
9 None
Good to see lots of love for zip in the answers here.
However it should be noted that if you are using a python version before 3.0, the itertools module in the standard library contains an izip function which returns an iterable, which is more appropriate in this case (especially if your list of latt/longs is quite long).
In python 3 and later zip behaves like izip.
in case your Latitude and Longitude lists are large and lazily loaded:
from itertools import izip
for lat, lon in izip(latitudes, longitudes):
process(lat, lon)
or if you want to avoid the for-loop
from itertools import izip, imap
out = imap(process, izip(latitudes, longitudes))
Iterating through elements of two lists simultaneously is known as zipping, and python provides a built in function for it, which is documented here.
>>> x = [1, 2, 3]
>>> y = [4, 5, 6]
>>> zipped = zip(x, y)
>>> zipped
[(1, 4), (2, 5), (3, 6)]
>>> x2, y2 = zip(*zipped)
>>> x == list(x2) and y == list(y2)
True
[Example is taken from pydocs]
In your case, it will be simply:
for (lat, lon) in zip(latitudes, longitudes):
... process lat and lon
for Lat,Long in zip(Latitudes, Longitudes):
This post helped me with zip(). I know I'm a few years late, but I still want to contribute. This is in Python 3.
Note: in python 2.x, zip() returns a list of tuples; in Python 3.x, zip() returns an iterator.
itertools.izip() in python 2.x == zip() in python 3.x
Since it looks like you're building a list of tuples, the following code is the most pythonic way of trying to accomplish what you are doing.
>>> lat = [1, 2, 3]
>>> long = [4, 5, 6]
>>> tuple_list = list(zip(lat, long))
>>> tuple_list
[(1, 4), (2, 5), (3, 6)]
Or, alternatively, you can use list comprehensions (or list comps) should you need more complicated operations. List comprehensions also run about as fast as map(), give or take a few nanoseconds, and are becoming the new norm for what is considered Pythonic versus map().
>>> lat = [1, 2, 3]
>>> long = [4, 5, 6]
>>> tuple_list = [(x,y) for x,y in zip(lat, long)]
>>> tuple_list
[(1, 4), (2, 5), (3, 6)]
>>> added_tuples = [x+y for x,y in zip(lat, long)]
>>> added_tuples
[5, 7, 9]

Categories

Resources