Python: объединение чисел в списке - PullRequest
0 голосов
/ 25 октября 2019

У меня есть список, скажем

x = [0,1,2,3,"a","b","cd"]

Я хочу сохранить наименьшее число и все буквы, следовательно, в примере это будет

x = [0,"a","b","cd"]

Как я могусделай это? В идеале код должен быть очень эффективным, поскольку я делаю это для миллионов списков.

Попытки: я попытался найти min (x), однако это приводит к ошибке, поскольку в списке есть строки

Ответы [ 6 ]

6 голосов
/ 25 октября 2019

Я думаю, что приведенный ниже код является наиболее эффективным. Это не требует дополнительной памяти и сложность O (N)

import sys
x = [0, 1, 2, 3, "a", "b", "cd"]
minimum = sys.maxsize # for python 3.x
# minimum = sys.maxint #for python 2
j = 0
for i in range(len(x)):
    if isinstance(x[i], str):
        x[j] = x[i]
        j+=1
    else:
        minimum = min(minimum, x[i])
print([minimum]+x[:j])

Вывод

[0, 'a', 'b', 'cd']
5 голосов
/ 25 октября 2019

попробуйте это:

Python 2.7

output = [s for s in x if isinstance(s, str)]
output.append(min(x))

#>>> output
#['a', 'b', 'cd', 0]

Python3:

output = [s for s in x if isinstance(s, str)]
output.append(min([i for i in x if isinstance(i, int)]))
4 голосов
/ 25 октября 2019

Вы можете использовать itertools.groupby

>>> x = [0,1,2,3,"a","b","cd"]
>>> [min(n, *g) if t == int else n for t, g in groupby(x, type) for n in g]
[0, 'a', 'b', 'cd']

Более эффективным было бы просто минимизировать целые числа и распаковать строки.

>>> x = [0,1,2,3,"a","b","cd"]
>>> grouped = [list(g) for t, g in groupby(x, type)]
>>> [min(grouped[0]), *grouped[1]]
[0, 'a', 'b', 'cd']
3 голосов
/ 25 октября 2019

Одним из вариантов будет использование метода .isnumeric() для поиска минимального числа при построении нового списка для строк. Это должно быть O (n). Не супер быстро, но и не медленно.

Вы можете сказать что-то вроде:

min_number = None
string_list = []

for i in x:
    if i.isnumeric():
        if min_number is None or i < min_number:
            min_number = i
    elif isinstance(i, str):
        string_list.append(i)

if min_number is not None:
    x = string_list.insert(0, min_number)
2 голосов
/ 25 октября 2019

Как-то так должно работать

def minNum(array):
    min = None
    numPos = []
    for i in array:
        if type(i) == int or type(i) == float:
            if min is None or i < min:
                min = i
                numPos.append(array.index(i))
            else:
                numPos.append(array.index(i))
        else:
            pass
    numPos.reverse()
    for j in numPos:
        if array[j] != min:
            del array[j]
    return array

Определенно не единственное решение, но оно довольно компактное и хорошо работает для всех тестов, которые я дал

2 голосов
/ 25 октября 2019

Я не думаю, что это будет наиболее эффективным, но вы можете разделить список на два списка - один с int s и один с string s - и затем найти min и затем присоединиться к ним. Это будет выглядеть примерно так:

x = [0, 1, 2, 'a', 'b', 'c']
nums = []
strings = []
for item in x:
    if isinstance(item, int):
        nums.append(item)
    else:
        strings.append(item)

Теперь, после того, как вы запустите это, вы можете получить min и затем снова присоединиться к спискам

result = [min(nums)] + chars

Это даст [0, 'a', 'b', 'c']

...