How to sort list of strings - python

I have an initial list of strings:
List1 = ["2,6,4,5", "3,7,4,2"]
I would like each string to be sorted in ascending order:
Output = ["2,4,5,6", "2,3,4,7"]
May I know how do I do that?

You can try splitting, sort, then join
List1 = ["2,6,4,5", "3,7,4,2"]
sortedList = []
for s in List1:
nums = s.split(",")
nums.sort()
sortedList.append(",".join(nums))
Thanks for pointing out that the above doesn't work for numbers > 10 and negative numbers, I forgot that it was sorting with strings. Although the question didn't really specify, it makes sense that sorting should be based on number rather than string so update:
for s in List1:
nums = s.split(",")
nums = list(map(int, nums))
nums.sort()
nums = list(map(str, nums))
sortedList.append(",".join(nums))

You could make use of ast.literal_eval in order to evaluating the strings as Python values:
import ast
List1 = ["2,6,4,5", "3,7,4,2"]
print([",".join(map(str, sorted(ast.literal_eval(item)))) for item in List1])
Out:
['2,4,5,6', '2,3,4,7']

Here's a way to do it using list comprehension
List1 = ["2,6,4,5", "3,7,4,2"]
Output = [','.join(sorted(lis)) for lis in [s.split(',') for s in List1]]
['2,4,5,6', '2,3,4,7']

Related

Is there a better way I can apply the count function to two sets of lists?

I have two binary lists, is there a better way of assigning the binary list containing more 1's to the variable moreOnes? Bellow is my attempt.
moreOnes = []
for i in len(list1):
if list1.count(1) > list2.count(1):
moreOnes = list1
else:
moreOnes = list2
You can use max function with lambda expression as a key:
moreOnes = max(list1, list2, key=lambda x: x.count(1))
If you want the list with more 1's, you don't need that loop, just the if statement inside. If you want it more succinct, you could also do:
moreOnes = list1 if list1.count(1) > list2.count(1) else list2

splitting a list in a better way using list comprehension

I have a simple list that I am splitting and concatenating. My code uses for loop and if condition and ugly. Can you suggest a better way using list comprehension?
My code
mylist = ['10.10.10.1','10.10.10.2,10.10.10.3,10.10.10.4,10.10.10.5','10.10.10.6']
mylist = [i.split(",") for i in mylist]
list =[]
for x,y in enumerate(mylist):
if len(y) == 1:
list.append(y[0])
else:
for z in y:
list.append(z)
print(list)
I am getting the below result and exactly the way i want
['10.10.10.1','10.10.10.2','10.10.10.3','10.10.10.4','10.10.10.5','10.10.10.6']
You want:
[s for string in mylist for s in string.split(',')]
Note, your original approach wouldn't be so bad if you just simplified. No need for enumerate and no need to check the length, so just:
final_list =[]
for sub in mylist:
for s in sub:
final_list.append(s)
By the way, you shouldn't shadow the built-in list. Use another name
I agree with #juanpa.arrivillaga. However hope we can avoid that second looping since he is checking for empty values returning while splitting
In [7]: s=['10.10.10.1','','10.10.10.2,10.10.10.3,10.10.10.4,10.10.10.5','10.10.10.6']
In [8]: [splitRec for rec in s for splitRec in rec.split(',') if splitRec]
Out[8]:
['10.10.10.1',
'10.10.10.2',
'10.10.10.3',
'10.10.10.4',
'10.10.10.5',
'10.10.10.6']
In [9]: s=['10.10.10.1',',,','10.10.10.2,10.10.10.3,10.10.10.4,10.10.10.5','10.10.10.6']
In [10]: [splitRec for rec in s for splitRec in rec.split(',') if splitRec]Out[10]:
['10.10.10.1',
'10.10.10.2',
'10.10.10.3',
'10.10.10.4',
'10.10.10.5',
'10.10.10.6']
Not a comprehension, but good anyway, I think.
','.join(mylist).split(',')
You can first just split each string on ',':
>>> mylist = ['10.10.10.1','10.10.10.2,10.10.10.3,10.10.10.4,10.10.10.5','10.10.10.6']
>>> split_str = [x.split(',') for x in mylist]
>>> split_str
[['10.10.10.1'], ['10.10.10.2', '10.10.10.3', '10.10.10.4', '10.10.10.5'], ['10.10.10.6']]
Then if you want to flatten it, you can use itertools.chain.from_iterable:
>>> from itertools import chain
>>> list(chain.from_iterable(split_str))
['10.10.10.1', '10.10.10.2', '10.10.10.3', '10.10.10.4', '10.10.10.5', '10.10.10.6']

Changed Nested list items to integer format

How do I filter or remove the .0 at the end of my numbers? I tried converting them to integers but lists don't allow that. Is regex my best option? I don't need to do any maths with the numbers. I just need to remove the .0 at the end.
all help welcome.
Nums = [['17001.0', '17001.0'], ['17001.0', '11001.0'], ['17001.0', '18001.0'], ['17001.0', '19001.0'],
['14001.0', '12001.0'], ['19001.0', '18001.0'], ['19001.0', '16001.0'], ['15001.0'], ['16001.0'],
['18001.0'], ['19001.0'], ['18001.0'], ['22.0'], ['22.0'], ['22.0'], ['19001.0']]
If you want list with integer elements then this may help you:
Nums = [['17001.0', '17001.0'], ['17001.0', '11001.0'], ['17001.0', '18001.0']]
a=[]
for c in Nums:
if len(c)>1:
for d in c:
a.append(int(float(d)))
else:
a.append(int(float(c)))
# a= [17001, 17001, 17001, 11001, 17001, 18001]
I believe this would be the simplest approach:
nozeros = []
for i in Nums:
nozeros.append([int(j.split('.')[0]) for j in i])
I tried converting them to integers byt lists don't alow that
That's completely wrong:
IntNums = []
for lst in Nums:
IntLst = []
for n in lst:
IntLst.append(int(float(n)))
IntNums.append(IntLst)
You couldn't convert strings into integers because they contained the '.0' suffix, but you could first convert them to floats and then to integers.
If you want to convert the list in place, you iterate using indices:
for i in range(len(Nums)):
for j in range(len(Nums[i])):
Nums[i][j] = int(float(Nums[i][j]))
You could use a list comprehension too:
Nums = [[int(float(n)) for n in lst] for lst in Nums]

How to merge n lists together item by item for each list

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))

Python: Appending the index number of a string item in a list to that item

For any given list of string items, e.g.
my_list = ['foo', 'bar', 'baz', 'foo']
How does one append the index number of each item to it's corresponding item in the list? Forming a new list with the format, e.g.
new_list = ['foo0', 'bar1', 'baz2', 'foo3']
My example list only has four items, but I'm interested in a generalised answer for an arbitrary number of string items (something that works as well for a list of 4,000 string items as it does for 4)
Cheers!
A simpler way:
new_list = [elm + str(index) for index, elm in enumerate(my_list)]
UPDATE: With Python 3.6+ and formatted strings literals you can get a more readable code:
new_list = [f'{elm}{index}' for index, elm in enumerate(my_list)]
A straight for loop would work:
counter = 0
new_list = []
for each_item in the_list:
new_list.append(each_item + str(counter))
counter += 1
A list comprehension with enumerate() would also be fine, but less readable:
new_list = [each_item + str(index) for each_item, index in enumerate(the_list)]
try this.
EDIT: Explanation: The function below takes a list as an input and returns a list with the element numbers appended to the item. The number appended to the end of each item in the list is padded with zeros based on the length of the input list. So a list of length 30 with have appended numbers 00 through 29; a list of 3901 will have appended numbers 0000 through 3900.
from numpy import log10
def numberedList(inlist):
i = 0
z = int(log10(len(inlist))) + 1
outlist = []
for element in inlist:
outlist.append(str(element) + str(i).zfill(z))
i = i + 1
return outlist
To create a list from a static list and a repeating list:
# need: ['A','B','C','First1','Middle1','Last1','First2','Middle2','Last2',...]
['A','B','C']+[s+str(n) for n in range(1,len(names)+1) for s in ['First','Middle','Last']]

Categories