работа со списками, игра похожая на зуму) #Python
Всем привет, есть задачка: Есть 3 списка:
one = [1, 2, 2, 3, 3, 3, 3, 3, 3, 1]
two = [2, 2, 3, 3, 3, 3, 3, 2, 1]
three = [3, 1, 1, 2, 2, 3, 3, 1, 1, 1, 3, 2, 2, 1, 1, 1, 3, 3]
нужно из каждого списка удалять цифры, если их 3. И в конечном итоге должен остаться пустой список Three.
Моя попытка:
for i in one:
if i == one.count(3):
one.remove(i)
Должно получится:
one=[1, 2, 2, 1]
two=[1]
three=[]
Можете дать подсказку? Спасибо.
Ответы (2 шт):
Я считаю, что такой результат не получится, если порядок цифр не имеет значения, а только сам факт наличия трех одинаковых в списке (согласно уточнению).
Если взять все эти списки и объединить, а потом убрать тройки одинаковых цифр, то останется список [1, 1, 3, 3]. Возможно, что-то не так с исходными данными. Мой код смог расстрелять список three по максимуму, чтобы в одном списке собрать три одинаковые цифры, а остатки переместил в список one.
from collections import Counter
one = [1, 2, 2, 3, 3, 3, 3, 3, 3, 1]
two = [2, 2, 3, 3, 3, 3, 3, 2, 1]
three = [3, 1, 1, 2, 2, 3, 3, 1, 1, 1, 3, 2, 2, 1, 1, 1, 3, 3]
for i in three:
# если в one/two лежит 2 или больше одинаковых числа
if i in one and Counter(one)[i]>=2:
one.pop (one.index(i))
one.pop (one.index(i))
three.pop (three.index(i))
if i in two and Counter(two)[i]>=2:
two.pop (two.index(i))
two.pop (two.index(i))
three.pop (three.index(i))
for i in three:
# если в one/two лежит 1 число, но при этом в three их два
if i in one and Counter(one)[i]==1 and Counter(three)[i]>=2:
one.pop (one.index(i))
three.pop (three.index(i))
three.pop (three.index(i))
if i in two and Counter(two)[i]==1 and Counter(three)[i]>=2:
two.pop (two.index(i))
three.pop (three.index(i))
three.pop (three.index(i))
for i in three:
# если в three остается 3 одинаковых числа, то убираем их
if Counter(three)[i]>=3:
three.pop (three.index(i))
three.pop (three.index(i))
three.pop (three.index(i))
# выстреливаем остатки в one
for i in three:
one.append(i)
three=[]
# показываем остатки
print (one, ' ', two, ' ', three)
Возможно код и не дал ожидаемого результата, но отработал выстрелы лучше, оставив на одну цифру меньше. Если в список three для моего кода добавить еще одну 1 и одну 3, то партия будет разыграна в ноль.
Циклы, срезы. Условия не пригодились.
one = [1, 2, 2, 3, 3, 3, 3, 3, 3, 1]
for i in one[:]: # делаем копию списка с помощью среза для итерирования
cnt = one.count(i)
for j in range(cnt - cnt % 3):
one.remove(i)
print(one)
[1, 2, 2, 1]
Старое:
Собираем числа в словарь число:кол-во повторений, потом удаляем в цикле количество чисел, кратное тройке.
one = [1, 2, 2, 3, 3, 3, 3, 3, 3, 1]
two = [2, 2, 3, 3, 3, 3, 3, 2, 1]
three = [3, 1, 1, 2, 2, 3, 3, 1, 1, 1, 3, 2, 2, 1, 1, 1, 3, 3]
def del_three(lst):
d = {}
for i in lst:
x = d.get(i, 0)
d[i] = x + 1
for k, v in d.items():
for i in range(v // 3 * 3): # или range(v - v % 3)
lst.remove(k)
return lst
print(del_three(one))
print(del_three(two))
print(del_three(three))
То же, но немного покороче с использованием collections.Counter()
from collections import Counter
one = [1, 2, 2, 3, 3, 3, 3, 3, 3, 1]
two = [2, 2, 3, 3, 3, 3, 3, 2, 1]
three = [3, 1, 1, 2, 2, 3, 3, 1, 1, 1, 3, 2, 2, 1, 1, 1, 3, 3]
def del_three(lst):
for k, v in Counter(lst).items():
for i in range(v - v % 3):
lst.remove(k)
return lst
print(del_three(one))
print(del_three(two))
print(del_three(three))
[1, 2, 2, 1]
[3, 3, 1]
[2, 1, 1]
Результат в задачке корректный только первый, во втором списке пять троек, две должны остаться. В третьем аналогично.