Перетворіть список Python із рядками все в малі чи великі регістри


261

У мене є змінна списку python, яка містить рядки. Чи є функція python, яка може перетворити всі рядки за один прохід у малі і навпаки, великі регістри?


Чому «за один прохід»? Чи задумуєтесь ви про можливість прийому декількох пропусків?
Джон Махін

Яким повинен бути вихід?
O.rka

Відповіді:


440

Це можна зробити зі списком розумінь. Вони в основному мають форму [function-of-item for item in some-list]. Наприклад, для створення нового списку, де всі елементи мають нижній регістр (або верхній регістр у другому фрагменті), ви використовуєте:

>>> [x.lower() for x in ["A","B","C"]]
['a', 'b', 'c']

>>> [x.upper() for x in ["a","b","c"]]
['A', 'B', 'C']

Ви також можете використовувати mapфункцію:

>>> map(lambda x:x.lower(),["A","B","C"])
['a', 'b', 'c']
>>> map(lambda x:x.upper(),["a","b","c"])
['A', 'B', 'C']

12
Функція карти працює так, як очікувалося в python2, однак у python3 ви загортаєте карту у список, наприклад:list(map(lambda x:x.upper(),["a","b","c"]))
Tom S

39
Друга пропозиція з картою є правильною, але марною. Немає сенсу робити лямбда-функцію . Просто використовуйтеmap(str.lower, ["A","B","C"])
фралау

1
Коли я намагаюся надрукувати список після цього дзвінка, нічого не змінюється. Чому так?
імітує

1
@mimic Трохи запізнився, але для людей, які стикаються з цим, я здогадуюсь, що ваше питання було, ймовірно, тим, що ви не присвоювали результат розуміння списку до свого списку. Просто виконання розуміння списку повертає значення, але не присвоює його змінній списку.
Майкл Колбер

52

Окрім легкого для читання (для багатьох людей), розуміння списку також виграють швидкісну гонку:

$ python2.6 -m timeit '[x.lower() for x in ["A","B","C"]]'
1000000 loops, best of 3: 1.03 usec per loop
$ python2.6 -m timeit '[x.upper() for x in ["a","b","c"]]'
1000000 loops, best of 3: 1.04 usec per loop

$ python2.6 -m timeit 'map(str.lower,["A","B","C"])'
1000000 loops, best of 3: 1.44 usec per loop
$ python2.6 -m timeit 'map(str.upper,["a","b","c"])'
1000000 loops, best of 3: 1.44 usec per loop

$ python2.6 -m timeit 'map(lambda x:x.lower(),["A","B","C"])'
1000000 loops, best of 3: 1.87 usec per loop
$ python2.6 -m timeit 'map(lambda x:x.upper(),["a","b","c"])'
1000000 loops, best of 3: 1.87 usec per loop

4
Чи знаєте ви причину, чому розуміння списку швидше, ніж карта?
Ніксуз

6
Це не завжди швидше. Ось приклад, коли це не так: stackoverflow.com/questions/1247486/… Але в цьому випадку це не набагато повільніше. Використання лямбда, очевидно, має велике значення. Є більше прикладів того, чому небезпечно довіряти своїй інтуїції з питань продуктивності, особливо в Python.
Нед Дейлі

3
у python 3, mapвиграє гонку, але нічого не робить :)
Жан-Франсуа Фабре

@NedDeily map(str.lower,["A","B","C"])найшвидший - python3.7.5
SHIVAM JINDAL


20

Ознайомлення зі списком - як я це зробив, це "піфонічний" спосіб. Наступна стенограма показує, як перетворити список у верхній регістр, а потім назад у нижній:

pax@paxbox7:~$ python3
Python 3.5.2 (default, Nov 17 2016, 17:05:23) 
[GCC 5.4.0 20160609] on linux
Type "help", "copyright", "credits" or "license" for more information.

>>> x = ["one", "two", "three"] ; x
['one', 'two', 'three']

>>> x = [element.upper() for element in x] ; x
['ONE', 'TWO', 'THREE']

>>> x = [element.lower() for element in x] ; x
['one', 'two', 'three']

2
помилка, використання listв якості змінної імені не є найкращим вибором :)
Жан-Франсуа Фабре

Ні, але, оскільки ім'я мало важливе для показаного методу, це не дуже актуально. Однак я зміню ім'я на випадок, якщо хтось хоче використовувати код таким, який є.
paxdiablo

магія stackoverflow: 250 голосів за рішення єдиного пітона, використовуючи лямбда, де не повинно !! добре 249 зараз
Жан-Франсуа Фабре

@ Jean-FrançoisFabre, не впевнений, чому ти вважаєш, що це рішення для Python-2. Як показує стенограма, вона чітко працює під Python 3.5.2. Насправді я просто перевірив це ще раз для підтвердження. ... проходить якийсь час, поки я розслідую ... Насправді, неважливо, здається, ви говорили про поточну прийняту відповідь, а не про цю, тому вам, мабуть, слід коментувати , а не тут. Без сумніву, чесна помилка. Ура.
paxdiablo

1
так, я не критикував твоїх (окрім listречей :)) Де ти думаєш, звідки ви отримали УФ, який нещодавно отримали? :)
Жан-Франсуа Фабре

7

Для цього зразка розуміння є найшвидшим

$ python -m timeit -s 's = ["один", "два", "три"] * 1000' '[x.upper for x in s]'
1000 петель, найкраще 3: 809 Usec на петлю

$ python -m timeit -s 's = ["один", "два", "три"] * 1000' 'карта (str.upper, s)'
1000 петель, найкраще 3: 1,12 мсек за петлю

$ python -m timeit -s 's = ["один", "два", "три"] * 1000' 'карта (лямбда x: x.upper (), s)'
1000 петель, найкраще 3: 1,77 мсек за петлю

5

студент запитує, інший студент із такою ж проблемою відповідає :))

fruits=['orange', 'grape', 'kiwi', 'apple', 'mango', 'fig', 'lemon']
newList = []
for fruit in fruits:
    newList.append(fruit.upper())
print(newList)

3
mylist = ['Mixed Case One', 'Mixed Case Two', 'Mixed Three']
print(list(map(lambda x: x.lower(), mylist)))
print(list(map(lambda x: x.upper(), mylist)))

2

Рішення:

>>> s = []
>>> p = ['This', 'That', 'There', 'is', 'apple']
>>> [s.append(i.lower()) if not i.islower() else s.append(i) for i in p]
>>> s
>>> ['this', 'that', 'there', 'is','apple']

Це рішення створить окремий список із малими елементами, незалежно від їх оригіналу. Якщо початковий регістр верхній, то list sзаголовок буде містити малі регістри відповідного елемента в list p. Якщо в початковому регістрі елемента списку вже є малі літери, list pто list sзастереження збереже корпус і збереже його в малому регістрі. Тепер ви можете використовувати list sзамість list p.


1

Якщо ваша мета полягає в узгодженні з іншим рядком шляхом перетворення за один прохід, ви також можете використовувати str.casefold().

Це корисно, якщо у вас є символи, які не мають права ascii, і збігаються з версіями ascii (наприклад, maße vs masse). Хоча str.lowerабо str.upperне вдасться в таких випадках str.casefold()пройти. Це доступно в Python 3, і ідея детально обговорюється з відповіддю https://stackoverflow.com/a/31599276/4848659 .

>>>str="Hello World";
>>>print(str.lower());
hello world
>>>print(str.upper());
HELLO WOLRD
>>>print(str.casefold());
hello world

1

Набагато простіше версія верхнього відповіді дається тут на @Amorpheuses.

З переліком значень у val:

valsLower = [item.lower() for item in vals]

Це добре працювало для мене із текстовим джерелом f = open ().


1

Ви можете спробувати скористатися:

my_list = ['india', 'america', 'china', 'korea']

def capitalize_list(item):
    return item.upper()

print(list(map(capitalize_list, my_list)))

0

Python3.6.8

In [1]: a = 'which option is the fastest'                                                                                                                                           

In [2]: %%timeit 
   ...: ''.join(a).upper() 
762 ns ± 11.4 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each)

In [3]: %%timeit  
   ...: map(lambda x:x.upper(), a) 
209 ns ± 5.73 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each)

In [4]: %%timeit  
   ...: map(str.upper, [i for i in a]) 
1.18 µs ± 11.3 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each)

In [5]: %%timeit 
   ...: [i.upper() for i in a] 
3.2 µs ± 64.1 ns per loop (mean ± std. dev. of 7 runs, 100000 loops each)

Якщо вам потрібен рядок або список як вихід, а не ітератор (це для Python3), порівняйте ''.join(string).upper()варіант із цим:

In [10]: %%timeit  
    ...: [i for i in map(lambda x:x.upper(), a)] 
4.32 µs ± 112 ns per loop (mean ± std. dev. of 7 runs, 100000 loops each)

0

Якщо ви намагаєтесь перетворити весь рядок у малі регістри списку, ви можете використовувати панди:

import pandas as pd

data = ['Study', 'Insights']

pd_d = list(pd.Series(data).str.lower())

вихід:

['study', 'insights']
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.