I am attempting to print out a list of tuples without square brackets whilst maintaining parentheses around the tuple.
For example, instead of the output being (current output):
[('1', '3'), ('1', '4'), ('2', '3'), ('2', '4')]
The output should be:
(1, 3) (1, 4) (2, 3) (2, 4)
Current source code below.
from itertools import product
if __name__ == '__main__':
input_lists = []
num_loops = int(input())
i = 0
while i < num_loops:
add_to_list = input()
input_lists.append(add_to_list.split(" "))
i += 1
result = ([i for i in product(*input_lists)])
print(''.join(str(result)))
List comprehension, str.format and str.join:
In [1045]: lst = [('1', '3'), ('1', '4'), ('2', '3'), ('2', '4')]
In [1046]: ' '.join('({}, {})'.format(i, j) for i, j in lst)
Out[1046]: '(1, 3) (1, 4) (2, 3) (2, 4)'
I suggest the int conversion and then unpack:
>>> from __future__ import print_function # for Python 2
>>> lst = [('1', '3'), ('1', '4'), ('2', '3'), ('2', '4')]
>>> print(*[tuple(map(int,t)) for t in lst])
(1, 3) (1, 4) (2, 3) (2, 4)
print(' '.join([str(int(i for i in tup)
for tup in list_of_tuples]))
Calling str() on a tuple produces the tuple itself, really, so I just did this for each item in the list. I also needed to make each item in the tuple an int so I also performed int() on each item in each tuple. The ' '.join() method will separate all of the items in the iterable passed in by a single whitespace. So... I passed in a list comprehension which performs str() on each item in the list.
Here's my take:
print(' '.join([str(tuple(map(int, i))) for i in L]))
A couple of points:
We use tuple with map to convert values from str to int.
str.join is one of the few instances where passing a list is more efficient than generator comprehension.
You can unpack the list.
lst = [(1, 2), (3, 4)]
print(*lst)
Output:
(1, 2) (3, 4)
With an array like
x = [('1', '3'), ('1', '4'), ('2', '3'), ('2', '4')]
you can do simply:
l = [(int(x),int(y)) for x,y in l]
print(*l)
Its output is similar to
output//(1, 3) (1, 4) (2, 3) (2, 4)
Related
I want to delete an element from a list of tuples and move the other items that had the same position.
Input:
a=[('201001', '-4'), ('201002', '2'), ('201003', '6')]
Desired output:
a=[('201001', '2'), ('201002', '6'), ('201003', 'na')]
I have tried the following code for it:
a[0](:- 1)
But I get SyntaxError: invalid syntax
I would appreciate it if you could suggest ways to solve this case.
Iterate through each element and set the tuple so that the second value is the value of the next element (except the last element because there is no element after it)
for i, val in enumerate(a):
try:
a[i] = (val[0], a[i+1][1])
except IndexError:
a[i] = (val[0], "na")
instead of error catching, you could also use the index:
arr_len = len(a) - 1
for i, val in enumerate(a):
if i == arr_len:
a[i] = (val[0], "na")
break
a[i] = (val[0], a[i+1][1])
Another way using zip:
a = [('201001', '-4'), ('201002', '2'), ('201003', '6')]
output = [(x, y) for (x, _), (_ ,y) in zip(a, [*a[1:], (None, 'na')])]
print(output) # [('201001', '2'), ('201002', '6'), ('201003', 'na')]
Here's a different way that lets you choose where you want to delete your number:
a = [('201001', '-4'), ('201002', '2'), ('201003', '6'), ('201004', '8'), ('201005', '3')]
def delete_item(position, arr): # position starting at 0, [(0,0), (1,1), (2,2), etc]
newNums = ([arr[x][1] for x in range(0, position)]
+ [arr[x][1] for x in range(position+1, len(arr))]
+ ['na'])
arr = [(arr[x][0], y) for x,y in zip(range(len(arr)), newNums)]
return arr
newTuple = delete_item(3, a)
Ouput:
[('201001', '-4'),
('201002', '2'),
('201003', '6'),
('201004', '3'),
('201005', 'na')]
Then you can keep putting the list of tuples in to remove a new number at a new position:
newTuple = delete_item(1, newTuple)
Output:
[('201001', '-4'),
('201002', '6'),
('201003', '3'),
('201004', 'na'),
('201005', 'na')]
Tuples are referenced the same way as a list which is a[0][-1] for the last element of the first tuple.
As tuples are immutable, you would be creating a new tuple every time you want to edit one.
One answer to your question would be to iterate through the values and update them like in the other answers.
A simpler way could be to first convert it into two lists, update and zip them back, like so:
from itertools import zip_longest
fst = list(map(lambda x: x[0], a))
snd = list(map(lambda x: x[1], a))
snd.pop(0)
a = list(zip_longest(fst, snd, fillvalue='na'))
I am trying to get integers value from a list of specific functions in a two different list and then try to store both list integer with combination of 2nd list integer.
let suppose we have two list,
list1 = ['A(0)','B(1)','C(3)','Z(4)','Z(7)','Z(2)', 'X(3)','X(2)',...]
list2 = ['A(0)','B(1)','C(3)','Z(7)','Z(3)','Z(5)', 'X(11)','X(4)',...]
now only the integer of Z from list1 and list2 will extract and store like this sequence,
Z1 = A(4,7)
Z1 = A(7,3)
Z2 = B(2,5)
first element of list1 and 2nd element of list2 in a sequence.
here is my code which i tried,
for line in list1:
if 'OUTPUT' in line:
print(line.split('Z(')[1].split(')')[0].strip())
for line in list2:
if 'OUTPUT' in line:
print(line.split('Z(')[1].split(')')[0].strip())
here is output
4 7 7 3 2 5
but still i didnt get value like,
Z1 = A(4,7)
Z1 = A(7,3)
Z2 = B(2,5)
def format_list(lst):
new = []
for sub in lst:
open_p = sub.index("(")
close_p = sub.index(")")
letter = sub[:open_p]
number = sub[open_p + 1 : close_p]
new.append((letter, number))
return new
list1 = ["A(0)", "B(1)", "C(3)", "Z(4)", "Z(7)", "Z(2)", "X(3)", "X(2)"]
list2 = ["A(0)", "B(1)", "C(3)", "Z(7)", "Z(3)", "Z(5)", "X(11)", "X(4)"]
lst1 = format_list(list1)
lst2 = format_list(list2)
The above code will format the lists as so:
lst1 = [('A', '0'), ('B', '1'), ('C', '3'), ('Z', '4'), ('Z', '7'), ('Z', '2'), ('X', '3'), ('X', '2')]
lst2 = [('A', '0'), ('B', '1'), ('C', '3'), ('Z', '7'), ('Z', '3'), ('Z', '5'), ('X', '11'), ('X', '4')]
From there, you'll be able to use filter() to find the places in which the numbers differentiate:
different_obj = list(filter(lambda x: x[0][1] != x[1][1], zip(lst1, lst2)))
print(different_obj)
Or if you rather, you don't need to use filter:
different_obj = []
for x, y in zip(lst1, lst2):
if x[1] != y[1]:
different_obj.append((x, y))
outputs:
[(('Z', '4'), ('Z', '7')),
(('Z', '7'), ('Z', '3')),
(('Z', '2'), ('Z', '5')),
(('X', '3'), ('X', '11')),
(('X', '2'), ('X', '4'))]
From there you should be able to organize different_obj to your goal.
[’A:2’,’B:2’,’C:2’,’D:1’]
How do you get rid of the colon and replace it with the comma? So, how do you get the above code and make it look like the one below?
[(’A’, 2), (’B’, 2), (’C’, 2), (’D’, 1)]
Using a list comprehension:
[(y[0], int(y[1])) for y in [x.split(':') for x in ['A:2', 'B:2', 'C:2', 'D:1']]]
Split each of the strings in the list on ::
>>> L = ['A:2','B:2','C:2','D:1']
>>> [tuple(x.split(':')) for x in L]
[('A', '2'), ('B', '2'), ('C', '2'), ('D', '1')]
you might want to look up map function and how split() works.
lambda allows you to craft your own function which map applies on or 'maps' to every single element of the iterable L
L = [’A:2’,’B:2’,’C:2’,’D:1’]
result = map(lambda x: tuple(x.split(':')), L)
if you wanted the values of the letters to be of type int, then:
result = map(lambda x: (x.split(':')[0], int(x.split(':')[0])), L)
>>> items = ['A:2', 'B:2', 'C:2', 'D:1']
>>> [(a, int(b)) for a, b in (item.split(':') for item in items)]
[('A', 2), ('B', 2), ('C', 2), ('D', 1)]
I have two list:
list1 = ['a','b','c']
list2 = ['1','2','3','4','5']
and I want to make the list:
list3 = [('1','a'),('2','b'),('3','c'),('4','a'),('5','b')]
In other words, do a cyclic combination between them. So, my question is: Which is the more efficient way to do that?
>>> from itertools import cycle
>>> list1 = ['a','b','c']
>>> list2 = ['1','2','3','4','5']
>>> zip(list2, cycle(list1))
[('1', 'a'), ('2', 'b'), ('3', 'c'), ('4', 'a'), ('5', 'b')]
As some have mentioned in the comments, if you want to cycle both lists and take the first n elements you can do that with,
>>> from itertools import islice, izip
>>> list(islice(izip(cycle(list2), cycle(list1)), 5))
[('1', 'a'), ('2', 'b'), ('3', 'c'), ('4', 'a'), ('5', 'b')]
Here's an alternative approach: A generator that continues the cyclic combination forever:
def cc(l1, l2):
i=0
c1 = len(l1)
c2 = len(l2)
while True:
yield (l1[i % c1], l2[i % c2])
i += 1
The literal answer to your question is then:
x=cc(list2, list1)
[next(x) for i in range(max(len(list1), len(list2)))]
[('1', 'a'), ('2', 'b'), ('3', 'c'), ('4', 'a'), ('5', 'b')]
But you now have a flexible foundation from which to derive all sorts of other interesting bits.
A previous stackoverflow question explains how to sort a list of strings alpha-numerically. I would like to sort a list of tuples alphanumerically by the tuple's first element.
Example 1:
>>> sort_naturally_tuple([('b', 0), ('0', 1), ('a', 2)])
[('0', 1), ('a', 2), ('b', 0)]
Example 2:
>>> sort_naturally_tuple([('b10', 0), ('0', 1), ('b9', 2)])
[('0', 1), ('b9', 2), ('b10', 0)]
Update: To emphasize the alphanumeric factor, please review example 2.
Using the second answer from the other question, generalized to support any method on item as the basis for getting the key:
import re
from operator import itemgetter
def sorted_nicely(l, key):
""" Sort the given iterable in the way that humans expect."""
convert = lambda text: int(text) if text.isdigit() else text
alphanum_key = lambda item: [ convert(c) for c in re.split('([0-9]+)', key(item)) ]
return sorted(l, key = alphanum_key)
print sorted_nicely([('b10', 0), ('0', 1), ('b9', 2)], itemgetter(0))
This is exactly the same as that answer except generalized to use any callable as the operation on item. If you just wanted to do it on a string, you'd use lambda item: item, if you wanted to do it on a list, tuple, dict, or set, you'd use operator.itemgetter(key_or_index_you_want), or if you wanted to do it on a class instance you could use operator.attrgetter('attribute_name_you_want').
It gives
[('0', 1), ('b9', 2), ('b10', 0)]
for your example #2.
Tuples are by default sorted by their elements, starting at the first. So simply do
L = [('b', 0), ('0', 1), ('a', 2)]
L.sort()
print L
# or create a new, sorted list
print sorted([('b', 0), ('0', 1), ('a', 2)])
The question you liked to talks about natural sorting, which is different from normal (alphanumeric) sorting.
Lets say you want to do natural sort on the first item only:
import re
def naturalize(item):
# turn 'b10' into ('b',10) which sorts correctly
m = re.match(r'(\w+?)(\d+)', item)
return m.groups()
# now sort by using this function on the first element of the tuple:
print sorted(L, key=lambda tup: naturalize(tup[0]))
As others have pointed out, sorted will use the first element of the tuple by default. If you wish to modify this default behavior you can specify a key to be used during the comparisons.
sorted([('b', 0), ('0', 1), ('a', 2)])
Will return the same as:
sorted([('b', 0), ('0', 1), ('a', 2)], key=lambda item: item[0])
To sort by the second element however try:
sorted([('b', 0), ('0', 1), ('a', 2)], key=lambda item: item[1])
The natsort module does this by default without any extra work
>>> from natsort import natsorted
>>> natsorted([('b', 0), ('0', 1), ('a', 2)])
[('0', 1), ('a', 2), ('b', 0)]
>>> natsorted([('b10', 0), ('0', 1), ('b9', 2)])
[('0', 1), ('b9', 2), ('b10', 0)]