Страницы

Поиск по вопросам

Показаны сообщения с ярлыком list. Показать все сообщения
Показаны сообщения с ярлыком list. Показать все сообщения

четверг, 9 апреля 2020 г.

BindingList и привязка данных

#c_sharp #net #winforms #list

                    
У меня есть лист в который я могу добавить\удалить какой-то объект , как сделать
чтобы на это событие сразу отреагировал ListBox? 
    


Ответы

Ответ 1



Надо привязать ListBox к коллекции // #r "System.Windows.Forms" using System.Windows.Forms; using System.ComponentModel; var bl = new BindingList() { 1, 2, 3 }; new Timer { Enabled=true, Interval=1000 } // для примера каждую секунду .Tick += (s, e) => bl.AddNew(); // добавляем новые элементы в bl var f = new Form(); var lb = new ListBox() { Parent = f, Dock = DockStyle.Fill, DataSource = bl // привязка ListBox к BindingList }; f.ShowDialog(); Если надо в ListBox выводить значение свойства, то в lb надо добавить ValueMember var lb = new ListBox() { DataSource = bl, ValueMember = "тут имя свойства"; }; Если в ListBox надо выводить изменения свойств объектов, то в объектах надо реализовать интерфейс INotifyPropertyChanged public class Data : INotifyPropertyChanged { // требуется для уведомления о изменении значения свойств. public event PropertyChangedEventHandler PropertyChanged = delegate {}; public int Id { get; internal set; } public long Value { get { return _Value; } internal set { if (_Value != value) { _Value = value; PropertyChanged(this, new PropertyChangedEventArgs("Value")); }}} long _Value = 0; } Работающий пример на c# тут. UPDATE в лист добавляю число 1, а в лист бокс должна вывестись не единица, а "Число 1" Проще всего сделать так class Data { public int Value { get; set; } public string Text { get { return "Число " + this.Value; } } } var bl = new BindingList() { new Data { Value = 1 } }; var lb = new ListBox() { Parent = f, DataSource = bl, ValueMember="Value", DisplayMember="Text" };

Ответ 2



Объявляем класс с данными: public class Person { public int Id { get; set; } public string Name { get; set; } } Создаем коллекцию объектов: var source = new BindingList() { new Person() { Id = 1, Name = "Ivan" } }; Настраиваем контрол и передаем ему данные: // свойство, которое будет отображаться listBox.DisplayMember = "Name"; // свойство, которое будет возвращаться в качестве значения выбранного айтема listBox.ValueMember = "Id"; listBox = source; После этого все изменения в source будут отображаться в контроле.

Ответ 3



Вам нужно воспользоваться ListControl.DataSource List someList = ...; listBox.DataSource = someList;

воскресенье, 8 марта 2020 г.

Как ускорить процесс поиска совпадение в двух списках

#c_sharp #list


Есть два файла. Считываю из них оба значения в списки. Хочу взять уникальные значения
из обоих списков, однако процесс поиска и сравнения идет очееень долго(строк в обоих
списках ~300к). Подскажите как ускорить процесс поиска и сравнения*?

 var lst1 = File.ReadAllLines(@ "D:\test\1.csv").ToList();
 var lst2 = File.ReadAllLines(@ "D:\\test\2.csv").ToList();

 var rez = lst2.Where(x => !MySequenceContains(lst1, x)).
 Select(q => string.Join(";", q)).ToList();

 }

 private bool MySequenceContains(List < string > x, string y) {
  bool contains = false;
  index++;
  label2.Text = index.ToString();
  foreach(var a in x) {
   // ToDo: tweak the string comparison as needed
   if (string.Compare(a.Split(';')[0], y.Split(';')[0], StringComparison.InvariantCultureIgnoreCase)
== 0 &&
    string.Compare(a.Split(';')[14], y.Split(';')[14], StringComparison.InvariantCultureIgnoreCase)
== 0) {
    contains = true;
    break;
   }
  }
  return contains;
 }

    


Ответы

Ответ 1



Во-первых, ваш код возвращает строки, которые есть во втором файле, но нет в первом. Он не возвращает строки, которые есть в первом, но нет во втором. Во-вторых, вы используете Split внутри цикла, т.е. одни и те же строки сплитите много раз. В-третьих, вы внутри цикла по одному файлу делаете цикл по другому (ищете это значение в другом файле. Если объемы файлов одинаковые, то алгоритм медленный N^2. Если предварительно выполнить Split для всех входных строк и отсортировать списки по вашему критерию, то отобрать неповторяющиеся элементы можно в одном цикле сразу по двум (отсортированным) спискам. Сложность получается 2N + 2NlogN(сортировка). Вот пример, извиняюсь, что нелаконично: private List my(List x, List y) { var rez = new List(); var lst1 = new List(x.Select(s => s.Split(';'))); var lst2 = new List(y.Select(s => s.Split(';'))); lst1.Sort(MyComarer.Comparer); lst2.Sort(MyComarer.Comparer); var isPresentInX = false; int j = 0; for (int i = 0; i < lst1.Count; i++) { if (j >= lst2.Count) { rez.Add(string.Join(";", lst1[i])); continue; } var comp = MyComarer.Comparer.Compare(lst1[i], lst2[j]); while (comp > 0 && j < lst2.Count) { if (!isPresentInX) rez.Add(string.Join(";", lst2[j])); j++; if (j < lst2.Count) { if (MyComarer.Comparer.Compare(lst2[j], lst2[j - 1]) != 0) isPresentInX = false; comp = MyComarer.Comparer.Compare(lst1[i], lst2[j]); } } if (comp != 0) rez.Add(string.Join(";", lst1[i])); else isPresentInX = true; } return rez; } private class MyComarer : IComparer { public static MyComarer Comparer { get; } = new MyComarer(); public int Compare(string[] x, string[] y) { var res = string.Compare(x[0], y[0], StringComparison.InvariantCultureIgnoreCase); if (res == 0) res = string.Compare(x[14], y[14], StringComparison.InvariantCultureIgnoreCase); return res; } }

Ответ 2



lst1.Concat(lst2).ToList() .GroupBy(x=>x.Split(';')[0]+x.Split(';')[14]) .Select(g=>g.First())

Ответ 3



Альтернативный вариант: использовать HashSet вместе с его методом ExceptWith При создании объекта HashSet ему можно передать IEqualityComparer, который будет использоваться для сравнения элементов. Он может выглядеть так: class MySequenceEqualityComparer : IEqualityComparer { public bool Equals(string x, string y) { var xSplit = x.Split(';'); var ySplit = x.Split(';'); return string.Compare(xSplit[0], ySplit[0], StringComparison.InvariantCultureIgnoreCase) == 0 && string.Compare(xSplit[14], ySplit[14], StringComparison.InvariantCultureIgnoreCase) == 0; } public int GetHashCode(string obj) { return -1; } } При этом основной код сведется к следующему: var lst1 = File.ReadAllLines(@ "D:\test\1.csv"); var lst2 = new HashSet(File.ReadAllLines(@ "D:\\test\2.csv"), new MySequenceEqualityComparer()); lst2.ExceptWith(lst1); Результат будет в переменной lst2

пятница, 28 февраля 2020 г.

Как получить числа из строки и корректно отсортировать?

#python #строки #list


Есть файл с числами через запятую, без пробелов. Необходимо считать его и вывести
в консоль отсортированный список по возрастанию и убиванию.
Вот мои попытки:

import re

try:
    file_path = open(input('Введите путь к файлу: '))
except IOError:
    print('File not found')
file_value = file_path.read()
file_numbers = re.findall('\d+', file_value)
# print(file_numbers)
# print(type(file_numbers))
sorted(file_numbers, key=int)
print(file_numbers)
sorted(file_numbers, key=int, reverse=True)
print(file_numbers)


Собственно результат:


['6', '2', '3', '13', '5', '1', '7', '9', '18', '20', '16', '12', '15', '14', '10',
'11', '17', '9', '19']
['6', '2', '3', '13', '5', '1', '7', '9', '18', '20', '16', '12', '15', '14', '10',
'11', '17', '9', '19']



В чем ошибка и как поправить? :(

Так же были попытки сделать вот так:

try:
    file_path = open(input('Введите путь к файлу: '))
except IOError:
    print('File not found')
file_value = file_path.read()
# file_numbers = re.findall('\d+', file_value)
file_numbers = []
for i in file_value:
    try:
        num = int(i)
        file_numbers.append(num)
    except ValueError:
        continue
# print(file_numbers)
# print(type(file_numbers))
sorted(file_numbers, key=int)
print(file_numbers)
sorted(file_numbers, key=int, reverse=True)
print(file_numbers)


И на выходе получил вообще бред:


[6, 2, 3, 1, 3, 5, 1, 7, 9, 1, 8, 2, 0, 1, 6, 1, 2, 1, 5, 1, 4, 1, 0, 1, 1, 1, 7,
9, 1, 9]
[6, 2, 3, 1, 3, 5, 1, 7, 9, 1, 8, 2, 0, 1, 6, 1, 2, 1, 5, 1, 4, 1, 0, 1, 1, 1, 7,
9, 1, 9]


    


Ответы

Ответ 1



И на выходе получил вообще бред: Ваш код sorted(file_numbers, key=int) правильно был написан, но sorted возвращает новый отсортированный список, не изменяя исходный, поэтому вам нужно было сделать так: file_numbers = sorted(file_numbers, key=int) Можно отсортировать "на месте", как вы и хотели, но для этого нужно будет использовать sort: file_numbers.sort(key=int)

Ответ 2



Прежде всего, после получения списка строк, превратите его в список чисел: file_numbers = [int(number) for number in file_numbers] Затем - чтобы максимально сохранить ваш код - используйте вместо функции sorted() метод списка sort() (для прямой сортировки списка на месте): file_numbers.sort() print(file_numbers) file_numbers.sort(reverse=True) # или - более ефективно - file_numbers.reverse() print(file_numbers) Вывод: [1, 2, 3, 5, 6, 7, 9, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20] [20, 19, 18, 17, 16, 15, 14, 13, 12, 11, 10, 9, 9, 7, 6, 5, 3, 2, 1]

среда, 26 февраля 2020 г.

Массив решетка Python

#python #массивы #list #arraylist


Нужна помощь в решении задачи

Заполните прямоугольный массив целыми числами по образцу (нули стоят на пересечении
строк и
столбцов с нечетными номерами, в остальных клетках стоят единицы).

Пример для n=5m=6
1 1 1 1 1 1
1 0 1 0 1 0
1 1 1 1 1 1
1 0 1 0 1 0
1 1 1 1 1 1


Все на что меня хватило

n, m = 5, 6
mtrx = [[((j+i)%2 + (i-1)%2) for j in range(m)] for i in range(n)]
for k in mtrx:
    print(*k)


Output

1 2 1 2 1 2
1 0 1 0 1 0
1 2 1 2 1 2
1 0 1 0 1 0
1 2 1 2 1 2

    


Ответы

Ответ 1



n, m = 5, 6 mtrx = [ [ 0 if j % 2 and i % 2 else 1 for j in range(m)] for i in range(n)] for k in mtrx: print(*k)

Ответ 2



Спасибо @extrn за обучение) Вариант: n, m = 5, 6 mtrx = [[(~j&1) | (~i)&1 for j in range(m)] for i in range(n)] for k in mtrx: print(*k) Еще один: n, m = 5, 6 mtrx= [[(1-j%2) | (i+1)%2 for j in range(m)] for i in range(n)] for k in mtrx: print(*k)

вторник, 25 февраля 2020 г.

Заполнение массива динамическими данными

#java #list


Использую библиотеку AndroidPlot и требуется сделать график по результатам вычислений.
Результаты записываются в List<>, но как их перенести на график?

Ругается: "expression exepted" в строчке:

Number[] series1Numbers = new Number[]{List resul};

    


Ответы

Ответ 1



Вообще у интерфейса Collection, к которому относится List, есть нативный метод приведения к массиву: Iteration[] iterationArray = iterationList.toArray(new Iteration[iterationList.size()]); Он, однако, здесь просто так не сработает - вам нужно по пути как-то преобразовать Iteration в Number, которые, насколько понимаю, друг от друга никак не наследуются. Я не уверен, может ли в этом методе производиться upcast (скорее всего, может), однако вероятнее всего вам необходимо просто в цикле перебрать список и заполнить массив.

Ответ 2



прописываем компонент для рисования графиков: Настраиваем графики в коде: package ru.alexanderklimov.test; import java.util.Arrays; import com.androidplot.series.XYSeries; import com.androidplot.xy.LineAndPointFormatter; import com.androidplot.xy.SimpleXYSeries; import com.androidplot.xy.XYPlot; import android.os.Bundle; import android.app.Activity; import android.graphics.Color; public class TestActivity extends Activity { private XYPlot mySimpleXYPlot; /** Called when the activity is first created. */ @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_test); // initialize our XYPlot reference: mySimpleXYPlot = (XYPlot) findViewById(R.id.mySimpleXYPlot); // Create a couple arrays of y-values to plot: Number[] series1Numbers = { 1, 8, 5, 2, 7, 4 }; Number[] series2Numbers = { 4, 6, 3, 8, 2, 10 }; // Turn the above arrays into XYSeries': // SimpleXYSeries takes a List so turn our array into a List XYSeries series1 = new SimpleXYSeries(Arrays.asList(series1Numbers), SimpleXYSeries.ArrayFormat.Y_VALS_ONLY, // Y_VALS_ONLY means use // the element index as // the x value "Series1"); // Set the display title of the series // same as above XYSeries series2 = new SimpleXYSeries(Arrays.asList(series2Numbers), SimpleXYSeries.ArrayFormat.Y_VALS_ONLY, "Series2"); // Create a formatter to use for drawing a series using // LineAndPointRenderer: LineAndPointFormatter series1Format = new LineAndPointFormatter( Color.rgb(0, 200, 0), // line color Color.rgb(0, 100, 0), // point color null); // fill color (none) // add a new series' to the xyplot: mySimpleXYPlot.addSeries(series1, series1Format); // same as above: mySimpleXYPlot.addSeries( series2, new LineAndPointFormatter(Color.rgb(0, 0, 200), Color.rgb(0, 0, 100), null)); // reduce the number of range labels mySimpleXYPlot.setTicksPerRangeLabel(3); // by default, AndroidPlot displays developer guides to aid in laying // out your plot. // To get rid of them call disableAllMarkup(): mySimpleXYPlot.disableAllMarkup(); } } Любопытно, что в двух местах код был подчёркнут, указывая на устаревшие конструкции. Видимо, разработчики не успели обновить примеры на сайте в соответствии с новой документацией. Последний штрих - в манифесте у тега application нужно прописать один атрибут: android:hardwareAccelerated="false" Запускаем проект и смотрим на результат. Удали этот код - XYSeries series1 = new SimpleXYSeries(Arrays.asList(series1Numbers), SimpleXYSeries.ArrayFormat.Y_VALS_ONLY, // Y_VALS_ONLY means use // the element index as // the x value "Series1"); // Set the display title of the series // same as above XYSeries series2 = new SimpleXYSeries(Arrays.asList(series2Numbers), SimpleXYSeries.ArrayFormat.Y_VALS_ONLY, "Series2"); И немного измени форматтер

пятница, 21 февраля 2020 г.

Как создать общий List<> для всех форм?(WinForms, C#)

#c_sharp #winforms #list


У меня есть две формы, одна добавляет в лист данные, вторая считывает, как можно
это реализовать?
    


Ответы

Ответ 1



как-то так static class InnerData { static public List AllData = new List(); } добавление InnerData.AllData.Add(data); чтение foreach(Data data in InnerData.AllData) { //something }

Ответ 2



Насколько я понимаю, Вам нужно создать некий объект, функцией которого будет хранить данные, которыми могут пользоваться другие объекты Вашего приложения. Следовательно Вам нужен объект, экземпляр которого будет единым для всего приложения, и будет создан единожды. А если ожидается работа из нескольких потоков с полями, свойствами и методами этого класса, то этот класс должен ещё и обеспечивать потокобезопасность. Для решения этой задачи отлично подходит такой паттерн, как Singleton (Одиночка). using System; using System.Collections.Generic; using System.Linq; using System.Linq.Expressions; namespace ConsoleApplication { public class MyDataClass { public String MyProperty { get; set; } } public sealed class ConcurrentDataSingleton { /// /// Объект для обеспечения потокобезопасного доступа к полям одиночки /// private readonly static object _lockObject = new object(); /// /// Коллекция данных /// private List _data; /// /// Статическое поле, хранящее ссылку на объект одиночки в управляемой куче /// private static ConcurrentDataSingleton instance; /// /// Метод получения ссылки на объект-одиночку /// /// public static ConcurrentDataSingleton GetInstance() { if (instance == null) instance = new ConcurrentDataSingleton(); return instance; } /// /// Закрытый конструктор, инициализирующий поля класса /// private ConcurrentDataSingleton() { this._data = new List(); } /// /// Метод добавления объекта в коллекцию (потокобезопасно) /// /// Объект данных public void AddData(MyDataClass data) { lock (_lockObject) { this._data.Add(data); } } /// /// Метод получения данных (потокобезопасно) /// /// Условие, по которому следует выбирать объекты из коллекции /// public List GetData(Expression> predicate) { lock (_lockObject) { return this._data.AsQueryable().Where(predicate).ToList(); } } } class Program { public static void Main() { //получаем ссылку на хранилище данных ConcurrentDataSingleton dataStore = ConcurrentDataSingleton.GetInstance(); //Добавление данных dataStore.AddData(new MyDataClass() { MyProperty = "value" }); //Получение данных List dataThatINeed = dataStore.GetData(mdc => mdc.MyProperty == "value"); } } }

воскресенье, 16 февраля 2020 г.

Как создать общий List<> для всех форм?(WinForms, C#)

#c_sharp #winforms #list


У меня есть две формы, одна добавляет в лист данные, вторая считывает, как можно
это реализовать?
    


Ответы

Ответ 1



как-то так static class InnerData { static public List AllData = new List(); } добавление InnerData.AllData.Add(data); чтение foreach(Data data in InnerData.AllData) { //something }

Ответ 2



Насколько я понимаю, Вам нужно создать некий объект, функцией которого будет хранить данные, которыми могут пользоваться другие объекты Вашего приложения. Следовательно Вам нужен объект, экземпляр которого будет единым для всего приложения, и будет создан единожды. А если ожидается работа из нескольких потоков с полями, свойствами и методами этого класса, то этот класс должен ещё и обеспечивать потокобезопасность. Для решения этой задачи отлично подходит такой паттерн, как Singleton (Одиночка). using System; using System.Collections.Generic; using System.Linq; using System.Linq.Expressions; namespace ConsoleApplication { public class MyDataClass { public String MyProperty { get; set; } } public sealed class ConcurrentDataSingleton { /// /// Объект для обеспечения потокобезопасного доступа к полям одиночки /// private readonly static object _lockObject = new object(); /// /// Коллекция данных /// private List _data; /// /// Статическое поле, хранящее ссылку на объект одиночки в управляемой куче /// private static ConcurrentDataSingleton instance; /// /// Метод получения ссылки на объект-одиночку /// /// public static ConcurrentDataSingleton GetInstance() { if (instance == null) instance = new ConcurrentDataSingleton(); return instance; } /// /// Закрытый конструктор, инициализирующий поля класса /// private ConcurrentDataSingleton() { this._data = new List(); } /// /// Метод добавления объекта в коллекцию (потокобезопасно) /// /// Объект данных public void AddData(MyDataClass data) { lock (_lockObject) { this._data.Add(data); } } /// /// Метод получения данных (потокобезопасно) /// /// Условие, по которому следует выбирать объекты из коллекции /// public List GetData(Expression> predicate) { lock (_lockObject) { return this._data.AsQueryable().Where(predicate).ToList(); } } } class Program { public static void Main() { //получаем ссылку на хранилище данных ConcurrentDataSingleton dataStore = ConcurrentDataSingleton.GetInstance(); //Добавление данных dataStore.AddData(new MyDataClass() { MyProperty = "value" }); //Получение данных List dataThatINeed = dataStore.GetData(mdc => mdc.MyProperty == "value"); } } }

пятница, 14 февраля 2020 г.

Конкатенация элементов двух списков в один (по индексу)

#python #list #список


Есть два списка одинаковой длины:

l1 = ["Hello", "Arcady", "My"]
l2 = ["World", "Petrovich", "Name"]


Необходимо получить один список, который бы соединял элемент каждого списка, например:

l3 = ["Hello World", "Arcady Petrovich", "My Name"]


Пытаюсь сделать через цикл, но он не правильно работает

def Concat(l1, l2):

    l3 = []
    for t1 in l1:
        for t2 in l2:
            if t2!="":
                l3.append(t1 + " + " + t2)
            else:
                l3.append(t1)
    return l3

    


Ответы

Ответ 1



l1 = ["Hello", "Arcady", "My"] l2 = ["World", "Petrovich", "Name"] l3 = [' '.join(x) for x in zip(l1, l2)] print(l3) # ['Hello World', 'Arcady Petrovich', 'My Name'] Алгоритм: zip составит список пар: list(zip(l1, l2)) # [('Hello', 'World'), ('Arcady', 'Petrovich'), ('My', 'Name')] В цикле будут перебираться пары и через join объединены: ' '.join(('Hello', 'World')) # 'Hello World' Если без функции, то: l3 = [x[0] + ' ' + x[1] for x in zip(l1, l2)] или: l3 = [a + ' ' + b for a, b in zip(l1, l2)]

Ошибка NoneType is not iterable в цикле

#python #list #null


В цикле выводит ошибку:


  TypeError: argument of type 'NoneType' is not iterable


Пытался исправить так:

if None in listUsers:
    listUsers.remove(None)
for user in listUsers:
    adj[user] = getFriends(user)


Ошибка остаётся прежней, но уже в строке с условием. Как это можно исправить?
    


Ответы

Ответ 1



Попробуйте заменить весь код из вопроса на следующий: adj = {user:getFriends(user) for user in listUsers if user} if listUsers else {}

Ответ 2



Вероятно у вас в прежнем коде случилось, что listUsers is None. Чтобы проверить это, напишите на консоли Питон: listUsers = None None in listUsers и на выводе вы получите TypeError: argument of type 'NoneType' is not iterable Значит, что вы нужны или применить тест перед вашим кодом (if listUsers is not None:) или использовать другой подход (например как в соседнем ответе).

четверг, 13 февраля 2020 г.

Как выбрать только русские слова из списка в python

#python #python_3x #list


У меня есть список слов как на английском так и на русском.
Например

list = ['apple', 'cat', 'яблоко', 'кот', 'building', 'машина', 'status',]


Как можно пройдя циклом вывести только русские слова?
В будущем планируется перебирать большой объем данных. И как это можно сделать с
учетом производительности?
    


Ответы

Ответ 1



Можно сделать через регулярное выражение, например: import re r = re.compile("[а-яА-Я]+") words = ['apple', 'cat', 'яблоко', 'кот', 'building', 'машина', 'status',] russian = [w for w in filter(r.match, words)] Для повышения скорости фильтрации на многоядерном процессоре можно дробить исходный список слов на куски (скажем, по 100000) и запускать фильтрацию в отдельных потоках с последующей конкатенацией результатов в один список.

Ответ 2



Простой вариант: [word for word in lst if 1039 < ord(word[0])] P.S.: Не стоит использовать имя переменной list, в языке уже есть одноименная функция. Update: Протестировал производительность - решение на регулярных выражениях работает на порядок быстрее.

воскресенье, 9 февраля 2020 г.

Как сгруппировать значения со списка

#python #python_3x #list #список


Дано

n = 4
l = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12]


Раз N у нас 4, то значит нужно сгруппировать значения в списке по четыре элемента.
Т.е. берем со списка первые 4 элемента и кладем их в лист, берем следующие 4 элемента
и так далее...
В итоге получаем такой новый список

r = [[1, 2, 3, 4], [5, 6, 7, 8], [9, 10, 11, 12]]


Как это можно реализовать?
    


Ответы

Ответ 1



Практически решение @strawdog , только зачем удалять, и автоматически получится для не кратного n n = 4 l = [1, 2, 3, 4, 5, 6, 7] r = [l[x:n+x] for x in range(0, len(l), n)] # [[1, 2, 3, 4], [5, 6, 7]]

Ответ 2



Самый простой вариант (при котором исходный список будет удален): n = 4 l = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12] r = [] while l: r.append(l[:n]) del l[:n] print(r) [[1, 2, 3, 4], [5, 6, 7, 8], [9, 10, 11, 12]] Если исходный список будет не кратен n, то результат будет такой: l = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13] [[1, 2, 3, 4], [5, 6, 7, 8], [9, 10, 11, 12], [13]]

Ответ 3



Разбивает список на более мелкие списки указанного размера. Используйте list() и range() для создания списка нужного размера. Используйте map () в списке и заполните его сращениями данного списка. Наконец, верните использование созданного списка. from math import ceil def chunk(lst, size): return list( map(lambda x: lst[x * size:x * size + size], list(range(0, ceil(len(lst) / size))))) chunk([1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12], 4) [[1, 2, 3, 4], [5, 6, 7, 8], [9, 10, 11, 12]]

Ответ 4



from itertools import islice def chunks_from(size, value): it = iter(value) while True: chunk = list(islice(it, size)) if chunk: yield chunk else: break a = list(chunks_from(4, [1, 2, 3, 4, 5, 6, 7])) print(a) # [[1, 2, 3, 4], [5, 6, 7]]

среда, 5 февраля 2020 г.

Как привести списки к одному общему виду?

#c_sharp #list


Есть два списка

List lst1 = new List(){"Бренд:Zara","Вес:40гр","Размер:20*20*20"};
List lst2 = new List(){"Бренд:Mario Muzi","Вес:1230гр","Фасовка:1",};


Я в итоге хочу объединть оба списка, чтобы вывести потом в Excell. Единственная проблема
- привести оба списка в единый формат, чтобы название колонок было одно. В итоге должно
получиться. 

    


Ответы

Ответ 1



List lst1 = new List() { "Бренд:Zara", "Вес:40гр", "Размер:20*20*20" }; List lst2 = new List() { "Бренд:Mario Muzi", "Вес:1230гр", "Фасовка:1", }; List titles = new List(); lst1.ForEach(s => titles.Add(s.Substring(0, s.IndexOf(":", StringComparison.InvariantCultureIgnoreCase)))); lst2.ForEach(s => titles.Add(s.Substring(0, s.IndexOf(":", StringComparison.InvariantCultureIgnoreCase)))); titles = titles.Distinct().ToList(); //print titles .... titles.ForEach(t => Console.Write(t + "\t")); Console.WriteLine(); //For lst 1 titles.ForEach(t => { var str = lst1.Where(s => s.Contains(t)) .Select(s => s.Substring(t.Length+1)) .FirstOrDefault(); Console.Write(string.IsNullOrWhiteSpace(str)?"--\t":str+"\t"); }); Console.WriteLine(); //for lst2 //....

Ответ 2



Вам нужно создать класс описывающий товар, затем объединять списки например так: List lst1 = new List() { new Product() { Brand = "Zara", Weight = 40, Size = "20*20*20" } }; List lst2 = new List() { new Product() { Brand = "Mario Muzi", Weight = 1230, Pre_Packing = 1 } }; List allList = lst1.Concat(lst2).ToList(); класс товара: public class Product { public string Brand { get; set; } public int Weight { get; set; } public string Size { get; set; } public int Pre_Packing { get; set; } }

Ответ 3



Мой вариант будет аналогичен предложению от @Leonid Malyshev. Для хранения объединённой информации мне понадобится вспомогательный следующий класс: class MergedEntityInfo { public string Name; public string Value1; public string Value2; } Теперь предположим, что формат описания свойства "<имя>:<значение>" всегда соблюдается для обоих списков, тогда проанализируем информацию хранящуюся в первом списке: var mergedEntityInfoMap = (from entityDescription in lst1 let info = entityDescription.Split(':').ToArray() let entity = new MergedEntityInfo { Name = info[0], Value1 = info[1] } select entity) .ToDictionary(x => x.Name); Далее пройдёмся по второму списку и дополним информацию в mergedEntityInfoMap: foreach (var info in lst2.Select(x => x.Split(':').ToArray())) { MergedEntityInfo mergedEntityInfo; if (mergedEntityInfoMap.TryGetValue(info[0], out mergedEntityInfo)) { mergedEntityInfo.Value2 = info[1]; } else { mergedEntityInfoMap[info[0]] = new MergedEntityInfo { Name = info[0], Value2 = info[1] }; } } Вот и всё, в mergedEntityInfoсодержится объединённая информация.

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

#python #python_3x #list


Например :

lst = ['1234','2341','123']

А должно стать:

lst = ['1234', '2341']


'123' - не подошло потому что там меньше четырех знаков
    


Ответы

Ответ 1



lst = ['1234', '2341', '123'] lst = [item for item in lst if len(item) >= 4]

Ответ 2



filter(lambda x: len(x) >= 4, lst)

Класс Stack в Java

#java #list #коллекции #stack


Какой класс лучше использовать для использования стека в java и почему он лучше?
    


Ответы

Ответ 1



Deque Для стэка рекомендуется использовать реализации интерфейса Deque. Интерфейс включает методы стэка: push, poll и peek. Стандартные реализации перечислены в документации, например: ArrayDeque — дэк на основе массива; LinkedList — связный список; ConcurrentLinkedDeque — потокобезопасная реализация. Выбор класса зависит от логики приложения (какие операции выполняются и как часто, как изменяется размер стэка) и потребует оценки производительности. В документации к ArrayDeque утверждается, что в качестве очереди он, скорее всего, будет быстрее LinkedList: ... This class is likely to be faster than Stack when used as a stack, and faster than LinkedList when used as a queue. так что, если не требуется доступ из нескольких потоков, разумно будет использовать ArrayDeque по умолчанию. Методы poll и peek в Deque унаследованы от Queue и работают в последовательности для очереди (FIFO). Для симуляции работы стэка можно использовать вместо них методы pollLast и peekLast. Queue Более удобный вариант: с помощью метода Collections.asLifoQueue преобразовать Deque в объект Queue, который ведет себя как стэк (LIFO). В этом случае будут корректно работать все методы и итераторы. Также не будут доступны лишние, не допустимые для стэка операции: Queue stack = Collections.asLifoQueue(new ArrayDeque<>()); stack.addAll(Arrays.asList("a", "b", "c", "d", "e")); //edcba stack.forEach(element -> System.out.println(element)); Stack не рекомендуется использовать Также есть стандартный класс java.util.Stack, но его не рекомендуется использовать. Из документации: A more complete and consistent set of LIFO stack operations is provided by the Deque interface and its implementations, which should be used in preference to this class. For example: Deque stack = new ArrayDeque(); Более полный и согласованный набор LIFO операций предоставляется через интерфейс Deque и его реализации, которые должны использоваться вместо этого класса. Например: Deque stack = new ArrayDeque(); т.е. класс сохранен для обратной совместимости, но вместо него нужно использовать реализации Deque. Это вызвано историческими причинами: в первой версии Java в реализации Stack допущены ошибки, например: Stack — конкретный класс, в отличие от остальных базовых коллекций, которые представлены интерфейсами: Set, List, Queue; класс наследуется от Vector, что концептуально неверно (поддерживаются лишние операции). Подробнее о проблемах Stack: Why Stack extends Vector in JDK? What are the negative aspects of Java class Stack inheriting from Vector?

Ответ 2



Мне кажется стоит использовать ArrayList или LinkedList. Второй будет использовать больше памяти, но зато операция добавления элемента в нём работает честные O(1), в отличии от ArrayList, у которого O(1) амортизированные. Не следует использовать класс Stack, потому что в нём все методы помечены как synchronized, что замедляет производительность в случае, если ваш стек использует только один поток (почти всегда именно так и происходит).

Ответ 3



Есть мнение - авторитетное - от одного из авторов красно-черных деревьев, что встроенные коллекции в java очень наворочены. Они напоминают швейцарские ножи - многое умеют. Но обратная сторона этого - не все операции имеют одинаковую алгоритмическую сложность. Поэтому лучше использовать коллекции с меньшим количеством методов, но которые хорошо используются именно вашей задаче. Посмотрите альтернативные реализации стека - не останавливайтесь на стандартной библиотеке.

понедельник, 3 февраля 2020 г.

Удалить уникальные значения из list

#python #list #count


Подобная тема была, но ответ мне не ясен. Почему удаляет из списка не все значения?

data = [1, 2, 3, 4, 5, 6]
for i in data:
     if data.count(i) == 1:
           data.remove(i)
print data


Печатает [2,4,6]
    


Ответы

Ответ 1



Самое главное, что Вы должны запонить - никогда не изменяйте размер массива во время прохождения по нему. Давайте посмотрим, как изменение размера массива влияет на логику цикла: In [3]: l = list(range(6)) In [4]: for x in l: ...: print(x) ...: l.remove(x) ...: 0 2 4 Взглянем на это через призму замечательных ASCII рисунков: +---+---+---+---+---+---+---+ | 0 | 1 | 2 | 3 | 4 | 5 | 6 | <- l +---+---+---+---+---+---+---+ ^ x Выведем на печать x и удалим его из списка: # print(0) +---+---+---+---+---+---+ | 1 | 2 | 3 | 4 | 5 | 6 | <- l +---+---+---+---+---+---+ ^ x Переместимся на следующий элемент, как завещал нам великий Guido van Rossum: +---+---+---+---+---+---+ | 1 | 2 | 3 | 4 | 5 | 6 | <- l +---+---+---+---+---+---+ ^ x Для закрепления, повторим действия: напечатаетаем, удалим и перейдем на следующую итерацию цикла: # print(2) +---+---+---+---+---+ | 1 | 3 | 4 | 5 | 6 | <- l +---+---+---+---+---+ ^ x (до перехода) +---+---+---+---+---+ | 1 | 3 | 4 | 5 | 6 | <- l +---+---+---+---+---+ ^ x (после перехода) Очевидно, что изменяя размер массива во время итерирования по нему, на свет рождается еще одно маленькое зло, которое может привести (и приводит) к ошибкам. Самый короткий рабочий эквивалент данного цикла представил @andreymal: data = [x for x in data if data.count(x) > 1] Но у представленных решений есть один общий недостаток - они имеют квадратичную сложность. In [9]: data = list(range(10000)) In [10]: %timeit [x for x in data if data.count(x) > 1] 1 loops, best of 3: 1.66 s per loop Стандартная библиотека Python предоставляет класс Counter, который подсчитает количество вхождений каждого элемента. Таким образом, скорость получится линейной (строго говоря, амортизированно линейной): In [11]: from collections import Counter In [12]: def f(xs): ....: counter = Counter(xs) ....: return [x for x in xs if counter[x] > 1] ....: In [13]: %timeit f(range(10000)) 100 loops, best of 3: 2.33 ms per loop

Ответ 2



Как писали в предыдущем ответе, массив меняется, а индекс не меняется, по сути получается лишнее смещение на следующий элемент при удалении другого элемента. Когда мне лень мудрить, а список чистить надо, я создаю копию массива: for i in tuple(data): if data.count(i) == 1: data.remove(i) (tuple вместо list, потому что он, говорят, производительнее) Когда мне мудрить не лень, я могу завести отдельный список под удаляемые элементы: rm = [] for i in data: if data.count(i) == 1: rm.append(i) for x in rm: data.remove(i) Когда я вспоминаю про существование генераторных выражений, я пишу вариант-однострочник: data = [x for x in data if data.count(x) > 1] Четвёртый известный мне вариант приведён в другом ответе.

Ответ 3



если добавить печать data = [1, 2, 3, 4, 5, 6] for i in data: print i if data.count(i) == 1: data.remove(i) print data получим 1 3 5 видимо в питоне, когда вы удаляете элемент, индекс остается, и вы шагаете через один. т.е. после удаления надо опять с тем же индексом проверять элемент. Проще всего запусть цикл по убыванию индекса вот так удалим всё (мой первый код на питоне :), наверняка можно красивее) data = [1, 2, 3, 4, 5, 6] i = len(data)-1 while i>=0 : if data.count(data[i]) == 1: data.remove(data[i]) i = i-1 print data

воскресенье, 2 февраля 2020 г.

Вставить элементы одного списка в другой с определённым шагом

#python_3x #list


Здравствуйте, стоит следующая задача:

Есть 2 txt файла (количество строк в каждом произвольно). Необходимо строки из одного
списка вставить в другой через определённый интервал, например, через каждые n строк.

f1 = open(r'c:\Исходная база.txt')
f2 = open(r'c:\Строки для добавления.txt')
list1 = f1.readlines()
list2 = f2.readlines()
f1.close()
f2.close()
i = 0
n = 2
while i + n <= 10:
    list1.insert(i * n, list2[i])
    i = i + 1
with open(r'c:\результат.txt', 'w') as res:
    for item in list1:
        res.write("{}".format(item))


В случае, если задать

while i + n <= len(list2):


list2 - файл откуда берём строки для подстановки, код работает как надо.

Однако, при 

while i + n <= len(list1):


Получаю ошибку:

list1.insert(i * n, list2[i])

IndexError: list index out of range


Прошу подсказать как реализовать подстановку строк из list2 в случае, если строк
в list2 меньше, чем в list1. То есть когда строки в list2 кончатся, подстановка строк
должна опять начаться с 0 элемента list2.

Исходные данные list1: 1, 2, 3, 4, .., m
Исходные данные List2: a, b, c, d, .., k
Результат должен быть: 1, a, 2, b, 3, c ... при n=2
                       1, 2, a, 3, 4, b, .. при n=3


При этом важно, чтобы строки подставлялись именно из list2 в list1. И когда строки
в list2 кончатся, они должны опять начать подставляться с 0 элемента.
    


Ответы

Ответ 1



Чтобы элементы по кругу возвращались (начинались с первого по окончанию), можно itertools.cycle() использовать. Чтобы по несколько элементов сразу обходить, можно zip(*[iterator]*n) идиому применить. Чтобы чередовать группы из первого итератора с элементами из второго и вернуть плоскую версию (без рекурсии) и обрезая ввод по меньшей длине аргументов: import itertools flatten = itertools.chain.from_iterable def interlaced(groups, items): return flatten(itertools.chain(group, [item]) for group, item in zip(groups, items)) Объединяя : n = 3 lines = interlaced(zip(*[itertools.cycle(f1)]*(n-1)), f2) output_file.writelines(lines) Пример: f1 = iter([1,2,3,4]) f2 = iter("abcde") it = interlaced(zip(*[itertools.cycle(f1)]*(n-1)), f2) print(*it) # -> 1 2 a 3 4 b 1 2 c 3 4 d 1 2 e

Ответ 2



Воспользуйтесь модулем itertools: In [1]: l1 = [1,2,3,4] In [2]: l2 = list('abcde') In [3]: from itertools import zip_longest, chain, cycle In [4]: list(chain.from_iterable(zip(cycle(l1), l2))) Out[4]: [1, 'a', 2, 'b', 3, 'c', 4, 'd', 1, 'e']

суббота, 1 февраля 2020 г.

Как осуществить слияние k сортированных списков

#python_3x #сортировка #list #память #время


Даны k отсортированных в порядке неубывания массивов натуральных чисел, каждое из
которых не превосходит 100. Требуется построить результат их слияния: отсортированный
в порядке неубывания массив, содержащий все элементы исходных k массивов.

Длина каждого массива не превосходит 10 ⋅ k.

Постарайтесь, чтобы решение работало за время k ⋅ log(k) ⋅ n, если считать, что входные
массивы имеют длину n.

Формат ввода

Первая строка входного файла содержит единственное число k, k ≤ 1024.

Каждая из следующих k строк описывает по одному массиву. Первое число каждой строки
равняется длине соответствующего массива, оставшиеся числа этой строки описывают значения
элементов этого же массива. Элементы массивов являются натуральными числами и не превосходят 100.

Формат вывода

Выходной файл должен содержать отсортированный в порядке неубывания массив, содержащий
все элементы исходных массивов.

Пример

Ввод

4
6 2 26 64 88 96 96
4 8 20 65 86
7 1 4 16 42 58 61 69
1 84

Вывод

1 2 4 8 16 20 26 42 58 61 64 65 69 84 86 88 96 96

Ограничение по времени выполнение скрипта 1 сек. для любого теста, ограничение по
используемой памяти: 10 МБ

Вот мой код:

import sys

int_str = ''
n = int(sys.stdin.readline().strip())
for i in range(int(n)):
    s = sys.stdin.readline().strip() + ' '
    count = int(s[:s.find(' ')])
    p, j = 0, 0
    for j in range(s.__len__()):
        if s[j] == ' ':
            p += 1
        if p == count+1:
            break
    int_str += s[s.find(' '):j]
    del (s,)

for i in sorted(int_str.lstrip().split(' '), key=lambda x: int(x) if x.isdigit() else 0):
    print(i, end=" ")


Ещё один вариант

import sys

n = int(sys.stdin.readline().strip())
int_list = []
for i in range(n):
    input = sys.stdin.readline().strip()
    data = list(map(int, input.split()))
    input = None
    n = data[0]
    a = data[1:n+1]
    int_list.extend(a)
    data = None

int_list.sort()

for li in int_list:
    sys.stdout.write(str(li) + ' ')
sys.stdout.write('\n')


Гномья сортировка

import sys

int_list = []
t = [0] * 101
n = int(sys.stdin.readline().strip())
for i in range(int(n)):
    s = sys.stdin.readline().strip()
    try:
        num = int(s[:s.find(' ')])
    except ValueError:
        continue
    for index, value in enumerate(s.split(' ')):
        if index == 0:
            continue
        elif index == num + 1:
            break
        try:
            t[int(value)] += 1
        except ValueError:
            pass
    del s

res = []
for i in range(101):
    res += [i] * t[i]

for r in res:
    print(r, end=' ')


Memory Limit и Time Limit близко
    


Ответы

Ответ 1



Так как в задаче есть ограничение на элементы массива: массивов натуральных чисел, каждое из которых не превосходит 100. то можно применить сортировку подсчётом, которая работает за линейное время. Но для C# возникает ещё одна проблема - это создание массива строк при считывании данных, которые на больших данных используют > 10Мб памяти. Я решила эту проблему с помощью запуска сборщика мусора. Моё решение: using System; using System.IO; namespace ConsoleApp { class Program { static void Main(string[] args) { short[] digitsCount = new short[101]; short k = Convert.ToInt16(Console.ReadLine()); string[] values; for (short i = 0; i < k; i++) { values = Console.ReadLine().Split(' '); for (short j = 1; j < values.Length; j++) { digitsCount[Convert.ToByte(values[j])]++; } GC.Collect(); } using (StreamWriter sw = new StreamWriter("output.txt")) { for (short i = 0; i < digitsCount.Length; i++) { for (short j = 0; j < digitsCount[i]; j++) { sw.Write(i + " "); } } } } } } Удачи на собеседовании!

Ответ 2



Сложность k * n Time Limit помогло убрать периодический вывод буфера, а не накопление его до N k = int(input()) count = {str(i): 0 for i in range(100)} total = 0 for list_index in range(k): a = input().split() size = int(a[0]) total += size if size > 0: for i in range(1, size + 1): count[a[i]] += 1 buff = [] for i in range(100): c = str(i) if i % 10 and buff: print(' '.join(buff), end=' ') buff = [] buff.extend([c] * count[c]) print(' '.join(buff)) Тест list + int() vs dict vs Counter from timeit import timeit from collections import Counter n = 10000000 str_list = [str(x) for x in range(n)] number = 10 print(timeit(""" for i in range(n): a[int(str_list[i]) % 100] += 1 """, setup='a = [0] * 100', number=number, globals=globals())) print(timeit(""" for i in range(n): d[str_list[i % 100]] += 1 """, setup='d = {str(i): 0 for i in range(100)}', number=number, globals=globals())) print(timeit(""" for i in range(n): d[str_list[i % 100]] += 1 """, setup='d = Counter(i for i in range(100))', number=number, globals=globals())) PyPy 3.5.3 (не понятно, почему Яндекс его не добавили): 6.919497203998617 1.7934346760011977 5.253608144004829 Python 3.7 27.728900675007026 17.81548438500613 25.83648096800607

Ответ 3



Тоже столкнулся с этой задачей. Начал с Python 3.6. Пробовал сортировку подсчетом и heapq.merge. Ни в какую не укладываюсь в 1 секунду на 20м тесте. Попробовал переписать на Go и сортировку подсчетом. Результат по времени абсолютно такой же как на Python. Видимо от языка не зависит. package main import ( "bufio" "fmt" "os" "strconv" "strings" ) func main() { const k = 100 reader := bufio.NewReader(os.Stdin) arraysNumString, _ := reader.ReadString('\n') arraysNumString = strings.TrimSuffix(arraysNumString, "\n") arraysNum, err := strconv.Atoi(arraysNumString) if err != nil { panic(err) } var counter [k]int for i := 0; i < arraysNum; i++ { inputString, _ := reader.ReadString('\n') inputString = strings.TrimSuffix(inputString, "\n") inputArray := strings.Split(inputString, " ") for idx, i := range inputArray { if idx == 0 { continue } j, err := strconv.Atoi(i) if err != nil { panic(err) } counter[j]++ } } for index, value:= range counter { for i := 0; i < value; i++ { fmt.Println(index) } } } Видимо нужно искать другой алгоритм или экономить на чтении строк.

Ответ 4



В задаче не оговорен запрет на использование стандартной библиотеки, поэтому моё решение выглядит следующим образом (для Python 3.4.3): from collections import Counter k = int(input()) a = Counter() for _ in range(k): a += Counter(map(int, input().split()[1:])) for key, c in sorted(a.items()): print("{} ".format(key) * c, end="") Ключевой момент здесь в том, что элементы в вводимых массивах не могут быть больше 100, а это значит, что количество ключей для Counter() не превысит это число. Даже в худшем случае, сортировка сотни целочисленных значений - простая задача. Опасения у меня вызывал только момент с суммированием Counter(), однако даже в последнем тесте, данный вариант затратил <5 mb памяти и уложился во время <0.7секунды.

Ответ 5



Реализация решения H. Case на основе встроенных типов. Результаты - 0.522s, 4.36Mb. n = int(input()) def counter_add(counter, value): if value in counter: counter[value] += 1 else: counter[value] = 1 counter = dict() for _ in range(n): ar = input().split() for i in ar[1:]: counter_add(counter, i) for i in range(101): i = str(i) if i in counter: print(' '.join([i] * counter[i]), end=' ')

Ответ 6



Я решила вот так - по-простому: k=int(input()) result={x:0 for x in range(0,101)} for i in range(k): current=input().split()[1:] for j in range(len(current)): cj = int(current[j]) result[cj] += 1 for key, v in result.items(): print("{} ".format(key) * v, end="")

Ответ 7



А я решил пойти путем использования одномерных векторов. Жаль, что Я не принял импорт NumPy... Пришлось тоже через сортировку подсчетом делать. Надеюсь, будет полезно и на такой вариант взглянуть. import sys import numpy as np k = sys.stdin.readline().strip() A = np.array([], dtype=np.uint8) for _ in range(int(k)): line = np.array(sys.stdin.readline().strip().split(" ")[1:], dtype=np.uint8) A = np.append(A, line) del line A = np.sort(A, kind="mergesort") A = A.tolist() print(*A)

Поиск элемента в списке

#python #python_3x #list


Код:

users = [12390312, 12313123, 57289234, 21837129398]

userstats = 21837129398

print("Начинаю поиск")
for element in users:
    if userstats == users:
        break
    else:
        print("'userstats' нет в списке 'users'")

print("'userstats' есть в списке 'users'")


К примеру в коде у меня есть список c id пользователей

users = [12390312, 12313123, 57289234, 21837129398]


И есть сервер который отправляет мне по команде id пользователя в переменную userstats.

Предположим он отправил мне переменную с id 21837129398

В теории код должен найти в списке этот id, если находит, нужно чтобы выполнялся
этот код: print("'userstats' есть в списке 'users'")
А если не находит нужно чтобы выполнялся этот код: print("'userstats' нет в списке
'users'")

Но с моим кодом у меня не выходит, не знаю что делать, пробовал гуглить, ничего не
нагуглил. Я ещё новичок в этой сфере, может что-то не знаю, подскажите :)
    


Ответы

Ответ 1



Для таких проверок можно воспользоваться оператором in. Если элемент есть в коллекции, то вернётся True, иначе - False. Код: users = [12390312, 12313123, 57289234, 21837129398] userstats = 21837129398 if userstats in users: print("'userstats' есть в списке 'users'") else: print("'userstats' нет в списке 'users'") stdout: 'userstats' есть в списке 'users' P. S.: Код можно сократить, используя аналог тернарного оператора: print("'userstats'", 'есть' if userstats in users else 'нет', "в списке 'users'")

Ответ 2



В случае бинарного ветвления можно воспользоваться индексированием при помощи булевого значения - False == 0 / True == 1: In [85]: verbs = ["нет", "есть"] In [86]: print(f"'userstats' {verbs[userstats in users]} в списке 'users'") 'userstats' есть в списке 'users'

Ответ 3



Как сделать это правильно с помощью in, вам уже написали. А вот почему не работает ваш код: for element in users: if userstats == users: break else: print("'userstats' нет в списке 'users'") Здесь у вас userstats - это один элемент. А users - это весь список. Очевидно, что условие userstats == users никогда не выполнится, т.к. один элемент не будет равен всему списку. Вам нужно было вместо userstats == users написать element == users, вот тогда бы ваш код заработал.

пятница, 31 января 2020 г.

Перемещение элементов в списке

#python #алгоритм #python_3x #list


У меня есть список:

lst = [1, 1, 0, 1, 0, 0, 1]


Если после единицы стоит ноль,то надо поменять их местами так,что если перед ней
стоит два нуля то,единица должна поменяться местами только с первым нулём.

То есть должно получиться так :

lst = [1, 0, 1, 0, 1, 0, 1]


Спасибо за помощь
    


Ответы

Ответ 1



i=0 while i < len(lst)-1: if lst[i] == 1 and lst[i+1] == 0: lst[i], lst[i+1] = lst[i+1], lst[i] i += 1 i += 1

Ответ 2



Вариант решения с преобразованием списка в строку, заменой и преобразованием строки обратно в список: In [67]: list(map(int, ''.join(map(str, lst)).replace('10', '01'))) Out[67]: [1, 0, 1, 0, 1, 0, 1] пошагово: In [68]: ''.join(map(str, lst)) Out[68]: '1101001' In [69]: ''.join(map(str, lst)).replace('10', '01') Out[69]: '1010101'

Ответ 3



Если входной список без изменения необходимо оставить: result = lst[:] # copy for i, (current, next_) in enumerate(zip(lst, lst[1:])): if current == 1 and next_ == 0: result[i+1], result[i] = result[i], result[i+1] # swap Результат: 1 0 1 0 1 0 1

Ответ 4



На ~10% быстрее чем в первом ответе: for i in (i + 0 for i in [j for j in [i for i in range(len(lst)-1) if lst[i] == 1 and lst[i+1] == 0]]): lst[i], lst[i + 1] = lst[i + 1], lst[i]

Как проверить содержится ли в строке какое-то слово из списка?

#python #строки #list #список


Например есть список 

words = ["Авто", "Велосипед", "Самолет"]


И например строка

str = "Быстрый автомобиль"


Нужно вернуть True, т.к. в строке есть "авто"
    


Ответы

Ответ 1



используя регулярные выражения, можно сделать такую проверку без цикла: In [12]: import re In [13]: chk_pat = '(?:{})'.format('|'.join(words)) In [14]: chk_pat Out[14]: '(?:Авто|Велосипед|Самолет)' In [15]: s = "Быстрый автомобиль" In [16]: bool(re.search(chk_pat, s, flags=re.I)) Out[16]: True In [17]: bool(re.search(chk_pat, 'строка', flags=re.I)) Out[17]: False PS если список слов проверки слишком большой 10+K bytes, то лучше, наверное, такие длинные регулярные выражения не использовать

Ответ 2



def is_part_in_list(str_, words): for word in words: if word.lower() in str_.lower(): return True return False Тест: words = ["Авто", "Велосипед", "Самолет"] str_ = "Быстрый автомобиль" print(is_part_in_list(str_, words)) Вывод: True

Ответ 3



words = ["Авто", "Велосипед", "Самолет"] str = "Быстрый автомобиль" for s in words: if str.lower().find(s.lower()) != -1: print("True") break

Ответ 4



print(any(word.lower() in str.lower() for word in words))