When i executed the following python script
list= (1,2,3,4,1,2,7,8)
for number in list:
item1= number
item2= list[list.index(item1)+2]
couple= item1, item2
print couple
the goal is to link each number with the second following
I obtain this result
(1, 3)
(2, 4)
(3, 1)
(4, 2)
(1, 3)
(2, 4)
(and then the index gets out of range but this is not the problem)
My question is why the number 1 in the fifth line is still coupled to the number 3 and how can i make that it is coupled to the number 7; idem for the number 2 in the sixth line that should be coupled to the number 8.
additional question
what do I do if i only want to make a list of the couples that start with 1: [(1,3), (1,7)]
list.index returns the offset of the first occurrence of the value in the list - thus if you do [1,1,1].index(1), the answer will always be 0, even though 1 and 2 are also valid answers.
Instead, try:
from itertools import islice, izip, ifilter
mylist = [1,2,3,4,1,2,7,8]
for pair in ifilter(lambda x: x[0]==1, izip(mylist, islice(mylist, 2, None))):
print pair
results in
(1, 3)
(1, 7)
xs.index(x) gives you the index of the first occurence of x in xs. So when you get to the second 1, .index gives you the index of the first 1.
If you need the index alongside the value, use enumerate: for i, number in enumerate(numbers): print number, numbers[i+2].
Note that I deliberately didn't use the name list. It's the name of a built-in, you shouldn't overwrite it. Also note that (..., ...) is a tuple (and therefore can't be changed), not a list (which is defined in square brackets [..., ...] and can be changed).
You have duplicates in the list so index always returns the first index.
Start your program with for index in range(len(list) - 1)
You are using .index which returns the first occurrence of number.
consider:
for number in range(len(list)):
item1= list[number]
item2= list[number+2]
couple= item1, item2
print couple
>>> zip(lst, lst[2:])
[(1, 3), (2, 4), (3, 1), (4, 2), (1, 7), (2, 8)]
To get only pairs (1, X):
>>> [(a, b) for (a, b) in zip(lst, lst[2:]) if a == 1]
[(1, 3), (1, 7)]
Recommended reading:
http://docs.python.org/tutorial/datastructures.html
http://docs.python.org/howto/functional.html
Related
init_tuple = [(0, 1), (1, 2), (2, 3)]
result = sum(n for _, n in init_tuple)
print(result)
The output for this code is 6. Could someone explain how it worked?
Your code extracts each tuple and sums all values in the second position (i.e. [1]).
If you rewrite it in loops, it may be easier to understand:
init_tuple = [(0, 1), (1, 2), (2, 3)]
result = 0
for (val1, val2) in init_tuple:
result = result + val2
print(result)
The expression (n for _, n in init_tuple) is a generator expression. You can iterate on such an expression to get all the values it generates. In that case it reads as: generate the second component of each tuple of init_tuple.
(Note on _: The _ here stands for the first component of the tuple. It is common in python to use this name when you don't care about the variable it refers to (i.e., if you don't plan to use it) as it is the case here. Another way to write your generator would then be (tup[1] for tup in init_tuple))
You can iterate over a generator expression using for loop. For example:
>>> for x in (n for _, n in init_tuple):
>>> print(x)
1
2
3
And of course, since you can iterate on a generator expression, you can sum it as you have done in your code.
To get better understanding first look at this.
init_tuple = [(0, 1), (1, 2), (2, 3)]
sum = 0
for x,y in init_tuple:
sum = sum + y
print(sum)
Now, you can see that what above code does is that it calculate sum of second elements of tuple, its equivalent to your code as both does same job.
for x,y in init_tuple:
x hold first value of tuple and y hold second of tuple, in first iteration:
x = 0, y = 1,
then in second iteration:
x = 1, y = 2 and so on.
In your case you don't need first element of tuple so you just use _ instead of using variable.
all I have a list of list of tuple here
A =[[(1, 52), (1, 12), (-1, -1)],[(-1, 23), (1, 42), (-1, -1)],[(1, -1), (-1, -1), (1, 42)]]
I wanted get the tuples containing the max values in second element of the tuple, column-wise.
I tried accessing columns like this
A[:,2]
But I get the error
TypeError: list indices must be integers, not tuple
Thanks in advance, Please let me know if you need any other information
Edit 1:
Desired output:
[(1, 52),(1, 42),(1, 42)]
[max(a,key=lambda x:x[1]) for a in zip(*A)]
output:
[(1, 52), (1, 42), (1, 42)]
Let me know if this works for you I will explain the answer.
You can access columns like this..
>>> list(zip(*A)[0])
[(1, 52), (-1, 23), (1, -1)]
>>> list(zip(*A)[1])
[(1, 12), (1, 42), (-1, -1)]
Explanation
zip https://docs.python.org/3/library/functions.html#zip
>>> x=[1,2,3]
>>> y=['a','b','c']
>>> z=['first','second','third']
>>> zip(x,y,z)
[(1, 'a', 'first'), (2, 'b', 'second'), (3, 'c', 'third')]
Now imagine x,y,z being the rows you had in A. By zip(rows) it returns 1st elements, 2nd elements, 3rd elements etc... There by returning us columns of the rows we passed.
Note: zip acts on multiple arguments passed in so we need to send multiple rows like x,y,z separately, not like [x,y,z] as a list. That is done by *A which separates the rows and passes to zip.
Now we got different columns
maxhttps://docs.python.org/3/library/functions.html#max
max(1,2) #Will return 2
max(cars,lambda x:x.speed) #Will give you the fastest car
max(cars,lambda x:x.capacity) #Will give you the biggest passenger car
max(tups,lambda x:x[1]) #Will give you the tuple with biggest 2nd element
List Comprehensionhttps://docs.python.org/3/tutorial/datastructures.html#list-comprehensions
A=[1,2,3]
[x**2 for x in A] #Will give you [1,4,9]
[x**3 for x in A] #Will give you [1,8,27]
Finally
[max(a,key=lambda x:x[1]) for a in zip(*A)]
Will give you max for each column!
You can try this:
A =[[(1, 52), (1, 12), (-1, -1)],[(-1, 23), (1, 42), (-1, -1)],[(1, -1), (-1, -1), (1, 42)]]
new_A = [max(a, key=lambda x: x[-1]) for a in zip(*A)]
Output:
[(1, 52), (1, 42), (1, 42)]
A is a list is lists of tuples. Basic Python does not recognised multiple-element subscripting, although Numpy and similar modules extend it. Your subscript expression :,2 is therefore interpreted as a tuple whose first element is a lice and whose second element is an integer, which (as the message explains) is not acceptable as a list index.
Unfortunately, "the tuples containing the max values in second element of the tuple, column-wise" isn't a terribly good description of the actual desired result.
I presume the answer you would like is [(1, 52), (1, 42), (1, 42)].
One relatively simple way to achieve this is to sort each of the sub-lists separately, taking the last element of each. this could be spelled as
result = [sorted(x, key=lambda z: z[1])[-1] for x in A]
The key argument to the sorted function ensures that each list is sorted on its second element, the
[-1] subscript takes the last (and therefore highest) element of the sorted list, and the for x in A ensure that each element of the output corresponds to an element (i.e., a list of three tuples) of the input.
I've searched around for a possible way to do this. I'm trying to make a loop that will go through my list of tuple pairs. Each index contains data that I will calculate and append to a list through each loop run until the end of the list of tuples is reached. Currently using a for loop, but I might use while loop.
index_tuple = [(1, 2), (2, 3), (3, 4)]
total_list = []
for index_pairs in index_tuple:
total_list.append(index_tuple[0][1] - index_tuple[0][0])
What I'm trying to get the loop to do:
(index_tuple[0][1] - index_tuple[0][0])#increment
(index_tuple[1][1] - index_tuple[1][0])#increment
(index_tuple[2][1] - index_tuple[2][0])#increment
Then I guess my final question is it possible to increment index position with a while loop?
Use a list comprehension. This iterates the list, unpacks each tuple to two values a and b, then it subtracts the first item from the second and inserts this new subtracted value into the new list.
totals = [b - a for a, b in index_tuple]
A list comprehension is the best solution for this problem, and Malik Brahimi's answer is the way to go.
Nevertheless, sticking with your for loop, you need to reference index_pairs in the body of the loop because this variable is assigned each tuple from index_tuple as the loop iterates. You do not need to maintain an index variable. A corrected version would be this:
index_tuple = [(1, 2), (2, 3), (3, 4)]
total_list = []
for index_pairs in index_tuple:
total_list.append(index_pairs[1] - index_pairs[0])
>>> print total_list
[1, 1, 1]
A cleaner version which unpacks the tuples from the list directly into 2 variables would be:
index_tuples = [(1, 2), (2, 3), (3, 4)]
total_list = []
for a, b in index_tuples:
total_list.append(b - a)
>>> print total_list
[1, 1, 1]
You also asked about using a while loop to achieve the same. Use an integer to keep track of the current index and increment it by one on each iteration of the loop:
index_tuples = [(1, 2), (2, 3), (3, 4)]
total_list = []
index = 0
while index < len(index_tuples):
total_list.append(index_tuples[index][1] - index_tuples[index][0])
index += 1
>>> print total_list
[1, 1, 1]
I am trying to make a program that will count the numbers in the list number, and would search for a sum of 10 in sequence_len numbers.
In the minute it gets a 10, it should stop.
1. With this code I have an error. what should I do?
total=total+(list_n[i+n])
IndexError: list index out of range
2.I want the first for to be stop if Im finding a sum of then. Is it write to "break" at the end as I did or should I write i=len(list_n)?
number = 1234
sequence_len = 2
list_n=[]
total=0
b="false"
list_t=[]
for j in str(number):
list_n.append(int(j))
c=len(list_n)
for i in list_n:
n=0
while n<sequence_len:
total=total+(list_n[i+n])
n=n+1
if total==10:
b=true
seq=0
while seq>sequence_len:
list_t.append(list_t[i+seq])
seq=seq+1
break
else:
total=0
if b=="true":
break
if b=="false":
print "Didn’t find any sequence of size", sequence_len
else:
print "Found a sequence of size", sequence_len ,":", list_t
You have a couple of errors. First with the basic:
b=true
This needs to the True, otherwise, python will look for the true variable.
Secondly, i actually contains the value of the variable for that iteration (loop). For example:
>>> l = ['a', 'b', 'c']
>>> for i in l: print i
a
b
c
Because of this, you cannot use it as an index, as indexes have to be integers. So, what you need to do is use enumerate, this will generate a tuple of both the index and the value, so something like:
for i, var in enumerate(list_n):
n = 0
An example of enumerate in action:
>>> var = enumerate([1,6,5,32,1])
>>> for x in var: print x
(0, 1)
(1, 6)
(2, 5)
(3, 32)
(4, 1)
And this statement should has logical problems I believe:
total = total + (list_n[i + n - 1])
If you want to get a sum of 10 from a list of numbers, you can use this brute-force technique:
>>> list_of_n = [1,0,5,4,2,1,2,3,4,5,6,8,2,7]
>>> from itertools import combinations
>>> [var for var in combinations(list_of_n, 2) if sum(var) == 10]
[(5, 5), (4, 6), (2, 8), (2, 8), (3, 7), (4, 6), (8, 2)]
So, if you want a 10 from 3 numbers in the list, you would put combinations(list_of_n, 3) instead of combinations(list_of_n, 2).
When you say
for i in list_n:
i will not refer to the indices, but to the list elements themselves. If you want just the indices,
for i in range(len(list_n)):
len(list_n) will give you the size of the list and range(len(list_n)) will give you a range of numbers starting from 0 and ending with len(list_n) - 1
I've got a list
a = [(1,2),(1,4),(2,6),(1,8),(3,6),(1,10),(1,6)]
If I say that:
for x in a:
if x[0]==1:
print x
I get the expected result : (1,2) (1,4) (1,8) (1,10) (1,6)
However I want to remove all the occurrences of all the tuples in the format (1,x),So
for x in a:
if x[0]==1:
a.remove(x)
I thought that all the occurences should be removed.However when i say
Print a
I get [(1,4),(2,6),(3,6),(1,6)]
Not all the tuples were removed. How do I do it.??
Thanks
I'd use list comprehension:
def removeTuplesWithOne(lst):
return [x for x in lst if x[0] != 1]
a = removeTuplesWithOne([(1,2),(1,4),(2,6),(1,8),(3,6),(1,10),(1,6)])
For me it's more pythonic than built-in filter function.
P.S. This function does not change your original list, it creates new one. If your original list is huge, i'd probably use generator expression like so:
def removeTuplesWithOne(lst):
return (x for x in lst if x[0] != 1)
This isn't the same approach as yours but should work
a = filter(lambda x: x[0] != 1, a)
You can use list comprehension like this, to filter out the items which have 1 as the first element.
>>> original = [(1, 2), (1, 4), (2, 6), (1, 8), (3, 6), (1, 10), (1, 6)]
>>> [item for item in original if item[0] != 1]
[(2, 6), (3, 6)]
This creates a new list, rather than modifying the existing one. 99% of the time, this will be fine, but if you need to modify the original list, you can do that by assigning back:
original[:] = [item for item in original if item[0] != 1]
Here we use slice assignment, which works by replacing every item from the start to the end of the original list (the [:]) with the items from the list comprehension. If you just used normal assignment, you would just change what the name original pointed to, not actually modify the list itself.
You can do it with a generator expression if you're dealing with huge amounts of data:
a = [(1,2),(1,4),(2,6),(1,8),(3,6),(1,10),(1,6)]
# create a generator
a = ((x,y) for x, y in a if x == 1)
# simply convert it to a list if you need to...
>>> print list(a)
[(1, 2), (1, 4), (1, 8), (1, 10), (1, 6)]