How to sort a list of strings?
Basic answer:
mylist = ["b", "C", "A"]
mylist.sort()
This modifies your original list (i.e. sorts in-place). To get a sorted copy of the list, without changing the original, use the sorted()
function:
for x in sorted(mylist):
print x
However, the examples above are a bit naive, because they don't take locale into account, and perform a case-sensitive sorting. You can take advantage of the optional parameter key
to specify custom sorting order (the alternative, using cmp
, is a deprecated solution, as it has to be evaluated multiple times - key
is only computed once per element).
So, to sort according to the current locale, taking language-specific rules into account (cmp_to_key
is a helper function from functools):
sorted(mylist, key=cmp_to_key(locale.strcoll))
And finally, if you need, you can specify a custom locale for sorting:
import locale
locale.setlocale(locale.LC_ALL, 'en_US.UTF-8') # vary depending on your lang/locale
assert sorted((u'Ab', u'ad', u'aa'),
key=cmp_to_key(locale.strcoll)) == [u'aa', u'Ab', u'ad']
Last note: you will see examples of case-insensitive sorting which use the lower()
method - those are incorrect, because they work only for the ASCII subset of characters. Those two are wrong for any non-English data:
# this is incorrect!
mylist.sort(key=lambda x: x.lower())
# alternative notation, a bit faster, but still wrong
mylist.sort(key=str.lower)
How to sort a list, only sorting strings?
Picked up this cool trick from @JonClements the other day.
Here goes:
gen = iter(sorted([x for x in lst if isinstance(x, str)]))
new_lst = [next(gen) if isinstance(x, str) else x for x in lst]
print(new_lst)
# ['Foo', 1, 2, 'Hello', 6, 'World', 3]
Sort the strings separately and create a generator expression from the sorted strings. In a list comprehension, pick objects alternately from the gen. exp. using a ternary conditional if only the items in the original position is a string, otherwise, pick an item (an integer) from the initial list.
Sort a list of strings using a user-provided order in Python
You can use sorted()
, and then generate the key
parameter by using map()
to map each letter to its priority (sorted()
then uses tuple comparison to generate the ordering):
data = ['ayyaaauu', 'shhasyhh', 'shaash']
ordering = ['s', 'y', 'u', 'h', 'a']
priorities = {letter: index for index, letter in enumerate(ordering)}
result = sorted(data, key=lambda x: tuple(map(lambda y: priorities[y], x)))
# Prints ['shhasyhh', 'shaash', 'ayyaaauu']
print(result)
How to Sort a Nested List of strings
Solution by Maintaining your Structure
If you can't really create a class wrapping the data in your nested List
(for whatever reason), you could use the collection stream and define the sorted
operation's logic as follows:
List<List<String>> listRes = data.stream()
.sorted((x, y) -> {
int res = x.get(0).compareTo(y.get(0)); //Comparing by name
if (res != 0) return res;
res = Integer.valueOf(x.get(1)).compareTo(Integer.valueOf(y.get(1))); //Comparing by age (numeric value)
if (res != 0) return res;
return x.get(2).compareTo(y.get(2)); //Comapring by city
})
.collect(Collectors.toList());
Link to test the code above:
https://ideone.com/RhW1VI
Alternative Solution
However, as it has been pointed out in the comments, a better approach would be to create a custom class representing your data in the nested List
. Perhaps a simple record if you're using Java 14 or later with a factory method to retrieve an instance of your class from a nested List
.
Then, with a stream you could map each nested list to your custom class and sort it with a Comparator
.
Here is a snippet of the implementation:
public static void main(String[] args) {
List<List<String>> data = /* ... your initialization ... */
List<MyClass> listSorted = data.stream()
.map(list -> MyClass.createMyClass(list))
.sorted(Comparator.comparing(MyClass::getName).thenComparing(MyClass::getAge).thenComparing(MyClass::getCity))
.collect(Collectors.toList());
System.out.println(listSorted);
}
Mapping record
record MyClass(String name, int age, String city, String code, String country) {
public static MyClass createMyClass(List<String> list) {
if (list == null || list.size() < 5) {
return null;
}
MyClass mc = new MyClass();
mc.name = list.get(0);
mc.age = Integer.valueOf(list.get(1));
mc.city = list.get(2);
mc.code = list.get(3);
mc.country = list.get(4);
return mc;
}
}
Here there is also a link with both implementations:
https://ideone.com/UK9trV
Python: how to sort a list of strings by substring relevance?
You can use difflib.SequenceMatcher, to achieve something very similar to your desired output:
>>> import difflib
>>> l = ["foo bar SOME baz TEXT bob", "SOME foo bar baz bob TEXT", "SOME foo TEXT", "foo bar SOME TEXT baz", "SOME TEXT"]
>>> sorted(l, key=lambda z: difflib.SequenceMatcher(None, z, "SOME TEXT").ratio(), reverse=True)
['SOME TEXT', 'SOME foo TEXT', 'foo bar SOME TEXT baz', 'foo bar SOME baz TEXT bob', 'SOME foo bar baz bob TEXT']
If you can't tell the only difference is that the position of the two elements "foo bar SOME TEXT baz"
and "SOME foo TEXT"
are swapped compared to your desired output.
Sort a list of strings in java in alphabetical order
You can create a custom Comparator
using Comparator.comparing
and Comparator.thenComparing
.
List<String> sortedIds = ids.stream().sorted(
Comparator.comparing((String s) -> s.substring(0, s.indexOf('-')))
.thenComparingInt(s -> Integer.parseInt(s.substring(s.indexOf('-') + 1))))
.collect(Collectors.toList());
Related Topics
Python Subprocess Get Children's Output to File and Terminal
How to Add an Extra Column to a Numpy Array
Shared-Memory Objects in Multiprocessing
Numpy Array Is Not JSON Serializable
Should I Always Specify an Exception Type in 'Except' Statements
How to Get If a Key Is Pressed Pygame
Temporarily Redirect Stdout/Stderr
Python: Finding Differences Between Elements of a List
Best Way to Find the Intersection of Multiple Sets
Shooting a Bullet in Pygame in the Direction of Mouse
Importerror: No Module Named Requests
Is There a List of Pytz Timezones
How to Pivot a Dataframe in Pandas
Differences Between Distribute, Distutils, Setuptools and Distutils2