Использование sorted
с re.findall
:
df = df.fillna('')
df[['Phone', 'Email']] = [sorted(t, key=lambda x:re.findall(r'(^.*@.*$)', x))
for t in df[['Phone', 'Email']].values]
Вывод:
ID Phone Email
0 A01 111111 abc@mail.com
1 A02 bcd@mail.com
2 A03 222222222 def@mail.com
Insight:
for t in df[['Phone', 'Email']].values
: итерации Phone
и Email
столбцы строка за строкой:
[('111111', 'abc@mail.com'),
('bcd@mail.com', ''),
('def@mail.com', '222222222')]
sorted(t, key=lambda x:re.findall(r'(^.*@.*$)', x))
теперь сортирует для каждого кортежа t
, проверьте, является ли элемент кортежа электронной почтой. Посмотрите, что происходит без sorted
и просто примените lambda
:
f = lambda x:re.findall(r'(^.*@.*$)', x)
[[f(i) for i in t] for t in df[['Phone', 'Email']].values]
# Output
[[[], ['abc@mail.com']],
[['bcd@mail.com'], []],
[['def@mail.com'], []]]
Теперь sorted
с key=f
будет сортировать , проверив элемент с помощью f
. После применения ключа пустой список выйдет на передний план (потому что пустой список []
оценивается как False
, тогда как [...]
равен True
: проверьте с помощью [] < [1]
).
[sorted(t, key=f) for t in df[['Phone', 'Email']].values]
, что приводит к:
[['111111', 'abc@mail.com'],
['', 'bcd@mail.com'],
['222222222', 'def@mail.com']]
И есть желаемый вывод!