polym
polym

Reputation: 658

Python sort strings alphabetically, lowercase first

I want to sort a given array of strings alphabetically using python, but lowercase words should appear first.

An example:

#!/usr/local/bin/python2.7
arr=['A','e','a','D','f','B']
arr.sort()
for s in arr: print s

Input:

A
e
a
D
f
B

Output (current):

A
B
D
a
e
f

Output (should be):

a
e
f
A
B
D

Upvotes: 4

Views: 26120

Answers (6)

Utsav
Utsav

Reputation: 5918

Using python 3.9

Sort inplace

arr=['A','e','a','D','f','B']
arr.sort(key=lambda x: (x.isupper(), x))
arr

Output

['a', 'e', 'f', 'A', 'B', 'D']

Note - while using sort method

Exceptions are not suppressed - if any comparison operations fail, the entire sort operation will fail (and the list will likely be left in a partially modified state).

Sort and assign to another variable keeping the original list intact

arr=['A','e','a','D','f','B']
sorted_arr = sorted(arr, key=lambda x: (x.isupper(), x))
sorted_arr

Output

['a', 'e', 'f', 'A', 'B', 'D']

Upvotes: 0

Arindam Roychowdhury
Arindam Roychowdhury

Reputation: 6521

Given : Alphanumeric string

Aim: To sort by rules

  1. Small letters first.
  2. Then capital letters.
  3. Then digits (even first, odd last) (Least priority).

    def func(l):
        if l.islower():
            return ord(l) - 32
        elif l.isupper():
            return ord(l) + 32
        elif l.isdigit():
            if int(l) % 2 == 0:
                return ord(l) + 200
            else:
                return ord(l) + 100
    
    print(*sorted(st, key=func), sep='')
    

Upvotes: 0

Tanveer Alam
Tanveer Alam

Reputation: 5275

We can use string.ascii_letters to get index of each letters to sort them.

arr = ['A','e','a','D','f','B']

import string

print sorted(arr, key=string.ascii_letters.index)

Results:

['a', 'e', 'f', 'A', 'B', 'D']

Or if you want to sort the original arr list use sort built-in function.

arr.sort(key=string.ascii_letters.index)
print arr

If the arr list is having words instead of single letters or alphabets we can use str.swapcase

arr = ['Abc', 'abc', 'aBc']
print sorted(arr, key=str.swapcase)

Yields:

['abc', 'aBc', 'Abc']

Upvotes: 3

Padraic Cunningham
Padraic Cunningham

Reputation: 180481

Some timings show that for sorting single characters creating a dict is the actually most efficient:

python2.7:

from string import ascii_letters

d = {b:a for a, b  in enumerate(ascii_letters)}

In [34]: timeit  sorted(s, key=str.swapcase)
10 loops, best of 3: 32.6 ms per loop

In [35]: timeit sorted(s,key=lambda x: (not x.islower(),x))
10 loops, best of 3: 51.4 ms per loop

In [37]: timeit (sorted(s ,key=d.get))
10 loops, best of 3: 22.4 ms per loop

Python3.4:

In [4]: timeit sorted(s,key=lambda x: (not x.islower(),x))
10 loops, best of 3: 57.7 ms per loop

In [5]: timeit  sorted(s, key=str.swapcase)
10 loops, best of 3: 41.2 ms per loop

In [6]: timeit (sorted(s ,key=d.get))
10 loops, best of 3: 21.1 ms per loop

Upvotes: 2

georg
georg

Reputation: 215019

To sort words, and not simply letters, just swap the case:

>>> words = ['alpha', 'Alpha', 'aLpha', 'Bravo', 'bRavo']
>>> sorted(words)
['Alpha', 'Bravo', 'aLpha', 'alpha', 'bRavo']
>>> sorted(words, key=str.swapcase)
['alpha', 'aLpha', 'bRavo', 'Alpha', 'Bravo']

Upvotes: 12

Ashwini Chaudhary
Ashwini Chaudhary

Reputation: 251106

Use a custom key method which checks whether the item is not .lower() and then compares the items itself. For 'A', 'D' and 'B' not x.islower() will return True and for other it is False, as True > False smaller case items will come first:

>>> arr = ['A','e','a','D','f','B']
>>> arr.sort(key=lambda x:(not x.islower(), x))
>>> arr
['a', 'e', 'f', 'A', 'B', 'D']

Upvotes: 10

Related Questions