This might sound like a stupid question but I have the following list:
list = ['a','b','c','d','a','b','c','d']
And I want to get common elements together to rearrange it as:
sorted_list = ['a','a','b','b','c','c','d','d']
Is there any built in function in python to do that?
Well to get sorted list you could just use:
sorted_list = sorted(list)
which gives the output ['a','a','b','b','c','c','d','d']
To sort and group elements by values:
list = sorted(list)
sorted_list = [[y for y in list if y==x] for x in list]
which gives the output [['a','a'],['b','b'],['c','c'],['d','d']]
Related
I'm using the following example for demonstration purposes.
[["apple",10],
["oranges",5],
["strawberies",2],
["pineapples",12],
["bananas",9],
["tomattoes",8],
["watermelon",1],
["mangos",7],
["grapes",11],
["potattoes",3]]
I want to get say the top 3 fruits by quantity (top 3 elements returned), however i don't want the order to change.
So the end result will be
[["apple",10],
["pineapples",12],
["grapes",11]]
Any help will be appreciated.
arr = [["apple",10],
["oranges",5],
["strawberies",2],
["pineapples",12],
["bananas",9],
["tomattoes",8],
["watermelon",1],
["mangos",7],
["grapes",11],
["potattoes",3]]
sorted_arr = sorted(arr,key=lambda x: x[1],reverse=True)[:3]
output = [elem for elem in arr if elem in sorted_arr]
print(sorted_arr)
print(output)
First, we sort the array in reverse order to get the first 3 elements. Then, we use list comprehension to loop through the original array and check if the elements are in the top 3. This preserves the order.
As you have probably heard before there is a sort method that you can apply to lists. You can pass in the key as a function that will indicate how you want your list to be sorted.
l = [["apple",10],
["oranges",5],
["strawberies",2],
["pineapples",12],
["bananas",9],
["tomattoes",8],
["watermelon",1],
["mangos",7],
["grapes",11],
["potattoes",3]]
l.sort(key = lambda x: x[1]) #to sort by second element
result = l[-3:] # To get the top three elements
I am trying to filter the following list:
tuple = [('7:29', 0.5), ('99:2', 0.35714285714285715), ('10:2', 0.35714285714285715)] using list comprehension, filtering based on the first elements from the tuples between the character ':'.
For example: filter = [7, 99], thus the result would be: new_tuple = [('7:29', 0.5), ('99:2', 0.35714285714285715)].
I tried the following solution:
filter_string = [str(item) for item in filter]
tuple_filtered = [(x,y) for (x,y) in tuples if x in filter]
but it returns an empty list and I don't have any idea how to fix it.
Can somebody please help me?
First when you apply this line:
filter_string = [str(item) for item in filter]
You apply str() function over a tuple object - making all the tuple in to a string.
for example - str(('99:2', 0.35714285714285715)) --> '(\\'99:2\\', 0.35714285714285715)'
Which in my sense just make it harder to parse.
Second, tuple is a saved name in python - do not use it and run it over!
it can cause very annoying bugs later on.
Finally, you can look at a tuple as a fixed size array which is indexed, which mean you can address the first element (that you want to filter by)
Something like that:
my_tuples = [('7:29', 0.5), ('99:2', 0.35714285714285715), ('10:2', 0.35714285714285715)]
my_filter = [7, 99]
filtered_list = [t for t in my_tuples if int(t[0].split(':')[0])
in my_filter]
[(x,y) for (x,y) in tuples if str(x.split(":")[0]) in filter_string ]
Equivalently:
op = []
for (x,y) in tuples :
if str(x.split(":")[0]) in filter_string:
op.append((x,y))
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 want to make one large list for entering into a database with values from 4 different lists. I want it to be like
[[list1[0], list2[0], list3[0], list4[0]], [list1[1], list2[1], list3[1], list4[1]], etc.....]
Another issue is that currently the data is received like this:
[ [ [list1[0], list1[1], [list1[3]]], [[list2[0]]], etc.....]
I've tried looping through each list using indexs and adding them to a new list based on those but it hasn't worked, I'm pretty sure it didn't work because some of the lists are different lengths (they're not meant to be but it's automated data so sometimes there's a mistake).
Anyone know what's the best way to go about this? Thanks.
First list can be constructed using zip function as follows (for 4 lists):
list1 = [1,2,3,4]
list2 = [5,6,7,8]
list3 = [9,10,11,12]
list4 = [13,14,15,16]
res = list(zip(list1,list2,list3,list4))
For arbitrtary number of lists stored in another list u can use *-notation to unpack outer list:
lists = [...]
res = list(zip(*lists))
To construct list of lists for zipping from you data in second issue use flatten concept to it and then zip:
def flatten(l):
res = []
for el in l:
if(isinstance(el, list)):
res += flatten(el)
else:
res.append(el)
return res
auto_data = [...]
res = list(zip(*[flatten(el) for el in auto_data]))
Some clarification at the end:
zip function construct results of the smallest length between all inputs, then you need to extend data in list comprehension in last code string to be one length to not lose some info.
So if I understand correctly, this is your input:
l = [[1.1,1.2,1.3,1.4],[2.1,2.2,2.3,2.4],[3.1,3.2,3.3,3.4],[4.1,4.2,4.3,4.4]]
and you would like to have this output
[[1.1,2.1,3.1,4.1],...]
If so, this could be done by using zip
zip(*l)
Make a for loop which only gives you the counter variable. Use that variable to index the lists. Make a temporary list , fill it up with the values from the other lists. Add that list to the final one. With this you will et the desired structure.
nestedlist = []
for counter in range(0,x):
temporarylist = []
temporarylist.append(firstlist[counter])
temporarylist.append(secondlist[counter])
temporarylist.append(thirdlist[counter])
temporarylist.append(fourthlist[counter])
nestedlist.append(temporarylist)
If all the 4 lists are the same length you can use this code to make it even nicer.
nestedlist = []
for counter in range(0,len(firstlist)): #changed line
temporarylist = []
temporarylist.append(firstlist[counter])
temporarylist.append(secondlist[counter])
temporarylist.append(thirdlist[counter])
temporarylist.append(fourthlist[counter])
nestedlist.append(temporarylist)
This comprehension should work, with a little help from zip:
mylist = [i for i in zip(list1, list2, list3, list4)]
But this assumes all the list are of the same length. If that's not the case (or you're not sure of that), you can "pad" them first, to be of same length.
def padlist(some_list, desired_length, pad_with):
while len(some_list) < desired_length:
some_list.append(pad_with)
return some_list
list_of_lists = [list1, list2, list3, list4]
maxlength = len(max(list_of_lists, key=len))
list_of_lists = [padlist(l, maxlength, 0) for l in list_of_lists]
And now do the above comprehension statement, works well in my testing of it
mylist = [i for i in zip(*list_of_lists)]
If the flatten concept doesn't work, try this out:
import numpy as np
myArray = np.array([[list1[0], list2[0], list3[0], list4[0]], [list1[1], list2[1], list3[1], list4[1]]])
np.hstack(myArray)
Also that one should work:
np.concatenate(myArray, axis=1)
Just for those who will search for the solution of this problem when lists are of the same length:
def flatten(lists):
results = []
for numbers in lists:
for output in numbers:
results.append(output)
return results
print(flatten(n))
I have a Python list like:
['user#gmail.com', 'someone#hotmail.com'...]
And I want to extract only the strings after # into another list directly, such as:
mylist = ['gmail.com', 'hotmail.com'...]
Is it possible? split() doesn't seem to be working with lists.
This is my try:
for x in range(len(mylist)):
mylist[x].split("#",1)[1]
But it didn't give me a list of the output.
You're close, try these small tweaks:
Lists are iterables, which means its easier to use for-loops than you think:
for x in mylist:
#do something
Now, the thing you want to do is 1) split x at '#' and 2) add the result to another list.
#In order to add to another list you need to make another list
newlist = []
for x in mylist:
split_results = x.split('#')
# Now you have a tuple of the results of your split
# add the second item to the new list
newlist.append(split_results[1])
Once you understand that well, you can get fancy and use list comprehension:
newlist = [x.split('#')[1] for x in mylist]
That's my solution with nested for loops:
myl = ['user#gmail.com', 'someone#hotmail.com'...]
results = []
for element in myl:
for x in element:
if x == '#':
x = element.index('#')
results.append(element[x+1:])