I would like to create a parallel list from my original list and then use sort_together
original = ['4,d', '3,b']
parallel list should create 2 lists like this:
lis1 = ['4', '3']
list2 = ['d', 'b']
I've tried using split but was only able to obtain a single list :(
[i.split(",", 1) for i in original]
You can use the zip(*...) trick together with .split:
list1, list2 = zip(*(x.split(",") for x in original))
Now this actually gives you two tuples instead of lists but that should be easy to fix if you really need lists.
You can use map and zip:
lis1, list2 = zip(*map(lambda x:x.split(","), original))
map will apply the function, passed as first argument (in this case, it simply splits strings on the comma separator) to every element of the iterable (list in this case) passed as second argument. After this, you'll have a map object which contains ['4', 'd'] and ['3', 'b']
the zip operator takes two (or more) lists and puts them side by side (like a physical zip would do), creating a lists for elements next to each other. For example, list(zip([1,2,3],[4,5,6])) is [[1.4],[2,5],[3.6]].
The unpacking * is necessary given that you want to pass the two sublists in the returned map object.
ini_list = [[4,'d'], [3,'b']]
print ("initial list", str(ini_list))
res1, res2 = map(list, zip(*ini_list))
print("final lists", res1, "\n", res2)
you can use this code for sort and get two list
list1 , list2 = list(sorted(t) for t in (zip(*(item.split(',') for item in orignal))))
for i in range(2):
s[i] = sorted([oi.split(',')[i] for oi in o])
Related
There's a list of lists (or it could be tuple of tuples). For example:
my_list = [
['A', 7462],
['B', 8361],
['C', 3713],
]
What would be the most efficient way to filter out all lists that have a value 'B' in them, considering that the number (or other values) might change?
The only way I came up with so far is using a for/in cycle (or rather a list comprehension) but it's very inefficient in this case, so I'd like to know if it's possible to avoid using a loop.
You can create a new list, filtering out the stuff you don't want. In python this is usually done with a list comprehension:
new_list = [sublist for sublist in my_list if sublist[0] != 'B']
You can use also use double-list comprehension.
[ [] ]
I want to separate different numbers in this list:
[([2437], [0.235]), ([4942], [0.217])]
and put them in new lists. Python returns length of this list equal to 2. I need to have two lists like these: [2437, 4942] and [0.235, 0.217].
How can I able to reach these lists from the above list in python?
You can use the following method for Python 3:
>>> my_list = [([2437], [0.235]), ([4942], [0.217])]
>>> sub_list1, sub_list2 = [[*item1, *item2] for item1, item2 in zip(*my_list)]
>>> sub_list1
[2437, 4942]
>>> sub_list2
[0.235, 0.217]
If it's always two tuples of two single item lists, another way to unpack:
l1, l2 = [[inner_list[i][0] for inner_list in my_list] for i in range(2)]
I want to join the elements of two lists into one list and add some characters, like so:
list_1 = ['some1','some2','some3']
list_2 = ['thing1','thing2','thing3']
joined_list = ['some1_thing1', 'some2_thing2', 'some3_thing3']
however i don't know in advance how many lists I will have to do this for, i.e. I want to do this for an arbitrary number of lists
Also, I currently receive a list in the following form:
list_A = [('some1','thing1'),('some2','thing2'),('some3','thing3')]
so I split it up into lists like so:
list_B = [i for i in zip(*list_A)]
I do this because sometimes I have an int instead of a string
list_A = [('some1','thing1',32),('some1','thing1',42),('some2','thing3', 52)]
so I can do this after
list_C = [list(map(str,list_B[i])) for i in range(0,len(list_B)]
and basically list_1 and list_2 are the elements of list_C.
So is there a more efficient way to do all this ?
Try this if you are using python>=3.6:
[f'{i}_{j}' for i,j in zip(list_1, list_2)]
If you using python3.5, you can do this:
['{}_{}'.format(i,j) for i,j in zip(list_1, list_2)]
also you can use this if you don't want to use formatted string:
['_'.join([i,j]) for i,j in zip(list_1, list_2)]
You can join function like this on the base list_A, itself, no need to split it for probable int values:
list_A = [('some1','thing1',32),('some1','thing1',42), ('some2','thing3', 52)]
["_".join(map(str, i)) for i in list_A]
Output:
['some1_thing1_32', 'some1_thing1_42', 'some2_thing3_52']
Update:
For you requirement, where you want to ignore last element for last tuple in your list_A, need to add if-else condition inside the list-comprehension as below:
["_".join(map(str, i)) if list_A.index(i) != len(list_A)-1 else "_".join(map(str, i[:-1])) for i in list_A ]
Updated Output:
['some1_thing1_32', 'some1_thing1_42', 'some2_thing3']
For ignoring the last element of every tuple in list_A, I found this to be the quickest way:
["_".join(map(str, i)) for i in [x[:-1] for x in list_A] ]
I have a long list that is made up of many tuples (over 100)that all contain 3 items that are strings
first_list = ('the','cat','went'),('back','too','scho'),('t/e','s/e/t','o/ve') etc
Many of the tuples are identically so i am using the set function to get out a unique set
Long_list = set(first_list)
i need the list in its original format , but i also need a duplicate list where the data has been cleaned
I need to remove all the "/" and Replace them with "#"
i can t seem to do this process. Initially i tried creating a foor loop to go through my list and then carry out the find and replace method.
The way i have done it gives me a new list that is made up of items , so the sets of tuples are not retained
for small_tuple in Long_list:
the_list = list(small_tuple)
for uncleaned_string in the_list:
time = uncleaned_string.replace('/','#')
last_list.append(time)
print last_list
Is there a way i can retain my original format of 3 items within tuple when i convert it back ?
tuple(myList) will convert myList into a tuple, provided that myList is something iterable like a list, a tuple, or a generator.
To convert a lists of lists in a list of tuples, using a list comprehension expression:
last_list = [tuple(x) for x in Long_list]
or, to also perform your string replacement:
last_list = [tuple(y.replace('/', '#') for y in x) for x in Long_list]
From Python's reference:
tuple( [iterable] )
Return a tuple whose items are the same and in the same order as iterable‘s items. iterable may be a sequence, a container that supports iteration, or an iterator object. If iterable is already a tuple, it is returned unchanged. For instance, tuple('abc') returns ('a', 'b', 'c') and tuple([1, 2, 3]) returns (1, 2, 3). If no argument is given, returns a new empty tuple, ().
tuple is an immutable sequence type, as documented in Sequence Types — str, unicode, list, tuple, bytearray, buffer, xrange. For other containers see the built in dict, list and [set] classes, and the collections module.
You could do something like the following using a list comprehension converted into a tuple:
for small_tuple in Long_list:
the_list = list(small_tuple)
last_list.append(tuple([uncleaned_string.replace('/','#') for uncleaned_string in the_list]))
print last_list
last_list = [tuple(s.replace('/', '#') for s in t) for t in Long_list]
Modified your code to fit your need
for small_tuple in Long_list:
the_list = list(small_tuple)
res=[]
for uncleaned_string in the_list:
time = uncleaned_string.replace('/','#')
res.append(time)
last_list.append(tuple(res))
print last_list
You can use an OrderedDict to remove the duplicates while preserving the order.
from collections import OrderedDict
x = OrderedDict.fromkeys(first_list)
Long_list = list(x)
Long_list contains unique tuples with order same as of first_list.
So I have a list of keys:
keys = ['id','name', 'date', 'size', 'actions']
and I also have a list of lists of vales:
values=
[
['1','John','23-04-2015','0','action1'],
['2','Jane','23-04-2015','1','action2']
]
How can I build a dictionary with those keys matched to the values?
The output should be:
{
'id':['1','2'],
'name':['John','Jane'],
'date':['23-04-2015','23-04-2015'],
'size':['0','1'],
'actions':['action1','action2']
}
EDIT:
I tried to use zip() and dict(), but that would only work if the list of values had 1 list, i.e. values = [['1','John','23-04-2015','0','action1']]
for list in values:
dic = dict(zip(keys,list))
I also thought about initialising a dic with the keys, then building the list of values on my own, but I felt that there had to be an easier way to do it.
dic = dict.fromkeys(keys)
for list in values:
ids = list[0]
names = list[1]
dates = list[2]
sizes = list[3]
actions = list[4]
and then finally
dic['id'] = ids
dic['name'] = names
dic['date'] = dates
dic['size'] = sizes
dic['action'] = actions
This seemed really silly and I was wondering what a better way of doing it would be.
>>> keys = ['id','name', 'date', 'size', 'actions']
>>> values = [['1','John','23-04-2015','0','action1'], ['2','Jane','23-04-2015','1','action2']]
>>> c = {x:list(y) for x,y in zip(keys, zip(*values))}
>>> c
{'id': ['1', '2'], 'size': ['0', '1'], 'actions': ['action1', 'action2'], 'date': ['23-04-2015', '23-04-2015'], 'name': ['John', 'Jane']}
>>> print(*(': '.join([item, ', '.join(c.get(item))]) for item in sorted(c, key=lambda x: keys.index(x))), sep='\n')
id: 1, 2
name: John, Jane
date: 23-04-2015, 23-04-2015
size: 0, 1
actions: action1, action2
This uses several tools:
c is created with a dictionary comprehension. Comprehensions are a different way of expressing an iterable like a dictionary or a list. Instead of initializing an empty iterable and then using a loop to add elements to it, a comprehension moves these syntactical structures around.
result = [2*num for num in range(10) if num%2]
is equivalent to
result = []
for num in range(10):
if num%2: # shorthand for "if num%2 results in non-zero", or "if num is not divisible by 2"
result.append(2*num)
and we get [2, 6, 10, 14, 18].
zip() creates a generator of tuples, where each element of each tuple is the corresponding element of one of the arguments you passed to zip().
>>> list(zip(['a','b'], ['c','d']))
[('a', 'c'), ('b', 'd')]
zip() takes multiple arguments - if you pass it one large list containing smaller sublists, the result is different:
>>> list(zip([['a','b'], ['c','d']]))
[(['a', 'b'],), (['c', 'd'],)]
and generally not what we want. However, our values list is just such a list: a large list containing sublists. We want to zip() those sublists. This is a great time to use the * operator.
The * operator represents an "unpacked" iterable.
>>> print(*[1,2,3])
1 2 3
>>> print(1, 2, 3)
1 2 3
It is also used in function definitions:
>>> def func(*args):
... return args
...
>>> func('a', 'b', [])
('a', 'b', [])
So, to create the dictionary, we zip() the lists of values together, then zip() that with the keys. Then we iterate through each of those tuples and create a dictionary out of them, with each tuple's first item being the key and the second item being the value (cast as a list instead of a tuple).
To print this, we could make a large looping structure, or we can make generators (quicker to assemble and process than full data structures like a list) and iterate through them, making heavy use of * to unpack things. Remember, in Python 3, print can accept multiple arguments, as seen above.
We will first sort the dictionary, using each element's position in keys as the key. If we use something like key=len, that sends each element to the len() function and uses the returned length as the key. We use lambda to define an inline, unnamed function, that takes an argument x and returns x's index in the list of keys. Note that the dictionary isn't actually sorted; we're just setting it up so we can iterate through it according to a sort order.
Then we can go through this sorted dictionary and assemble its elements into printable strings. At the top level, we join() a key with its value separated by ': '. Each value has its elements join()ed with ', '. Note that if the elements weren't strings, we would have to turn them into strings for join() to work.
>>> list(map(str, [1,2,3]))
['1', '2', '3']
>>> print(*map(str, [1,2,3]))
1 2 3
The generator that yields each of these join()ed lines is then unpacked with the * operator, and each element is sent as an argument to print(), specifying a separator of '\n' (new line) instead of the default ' ' (space).
It's perfectly fine to use loops instead of comprehensions and *, and then rearrange them into such structures after your logic is functional, if you want. It's not particularly necessary most of the time. Comprehensions sometimes execute slightly faster than equivalent loops, and with practice you may come to prefer the syntax of comprehensions. Do learn the * operator, though - it's an enormously versatile tool for defining functions. Also look into ** (often referred to with "double star" or "kwargs"), which unpacks dictionaries into keyword arguments and can also be used to define functions.