Страницы

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

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

пятница, 20 марта 2020 г.

Как составить список уникальных числовых комбинаций разделённых пробелами

#python #python_3x #список #комбинаторика


Мне нужно составить список уникальных числовых комбинаций которые нужно будет разделить
пробелами через каждый третий символ.
Я нашел такой вариант:

test = list(itertools.combinations('0123456789', 9))


Получается список кортежей: 

[('0', '1', '2', '3', '4', '5', '6', '7', '8'), ('0', '1', '2', '3', '4', '5', '6',
'7', '9') ...


Ума не приложу как его можно превратить в такой список: 

['012 345 678', '012 345 679', '012 345 689', ...


Подскажите пожалуйста какой нибудь способ решить эту задачку?
    


Ответы

Ответ 1



import itertools a = list(itertools.combinations('0123456789', 9)) b =[[''.join(y[i:i+3]) for i in range(0, len(y), 3)] for y in a] res = [' '.join(x) for x in b] print(res) ['012 345 678', '012 345 679', '012 345 689', '012 345 789', '012 346 789', '012 356 789', '012 456 789', '013 456 789', '023 456 789', '123 456 789']

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

Свой List из array

#cpp #массивы #классы #указатели #список


Пытаюсь создать свой list из array

есть структура 

template 
struct Node {
    T data;
    Node* next; 
};


собственно функция 

template 
Node* arrayToList(const T tab[], size_t size){

Node *node = new Node;
for(int i=0;idata = tab[i];
node->next = new Node;
}
}


в main 

    int tabi[] = {2,1,4,3,6,5,7,8};
size_t sizei = sizeof(tabi)/sizeof(tabi[0]);
Node *listAi = arrayToList(tabi,sizei);


так вот проблема в том что не могу править созданный экземпляр Node тут node->next
= new Node; я создаю экземпляр , а как в него значение из массива занести ?  
    


Ответы

Ответ 1



Не понятно, в чем состоит ваша проблема Поэтому я предложу код, который позволяет заполнить список элементами массива. Надеюсь, что если это не то, что вам нужно, то вы об этом сообщите мне в своем комментарии к ответу. Вот демонстрационная программа #include template struct Node { T data; Node *next; }; template Node * arrayToList( const T a[], size_t n ) { Node *head = nullptr; Node **current = &head; for ( size_t i = 0; i < n; i++, current = &( *current )->next ) { *current = new Node { a[i], nullptr }; } return head; } template void displayList( Node *head ) { for ( ; head; head = head->next ) std::cout << head->data << ' '; } int main() { int a[] = { 2, 1, 4, 3, 6, 5, 7, 8 }; const size_t N = sizeof( a ) / sizeof( *a ); for ( int x : a ) std::cout << x << ' '; std::cout << std::endl; Node *list = arrayToList( a, N ); displayList( list ); std::cout << std::endl; } Ее вывод на консоль: 2 1 4 3 6 5 7 8 2 1 4 3 6 5 7 8 Если ваш компилятор не поддерживает список инициализации для оператора new, то предложение *current = new Node { a[i], nullptr }; вы можете заменить на следующие предложения *current = new Node; ( *current )->data = a[i]; ( *current )->next = nullptr; Либо вы можете написать для класса Node конструктор, чтобы можно было бы опять записать все в одну строчку, как, например *current = new Node( a[i], nullptr );

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

Сравнение двух списков состоящих из массивов

#c_sharp #массивы #список #сравнение


Есть два списка List list1 и list2. Элементы в них могут совпадать. 
Мне нужно получить новый список list3 в который войдут элементы из list2, которых
не было в list1.

Я пытаюсь реализовать это так, но условие не работает и на выходе список пустой.

List list3 = list2.Where(x => !list1.Contains(x)).ToList();


Реализовал это так, но не горел желанием форы использовать, хотелось бы разобраться
почему не работал первый вариант.

for (byte i = 0; i < list2.Count; ++i)
    for (byte j = 0; j < list1.Count; ++j)
        {
            if (list2[i].SequenceEqual(list1[j]))
                list3.Add(list2[i]);
        }

    


Ответы

Ответ 1



Первый вариант не работал потому, что Contains сравнивает через Equals, а равенство по Equals для массивов есть равенство ссылок. А вам ведь нужно SequenceEqual вместо этого. Поэтому можно написать свой вариант Contains: x => !list1.Any(y => y.SequenceEqual(x))

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

Почему при добавлении (append) списка к самому себе создается бесконечно вложенный список?

#python #список #append


Добрый день! Хотел бы понять почему функция append создает бесконечно вложенный список,
если в аргумент вписать список который вызывает эту функцию.

l=[1,2,3]
l.append(l)

    


Ответы

Ответ 1



Ответ на этот вопрос в англоязычной версии SO... In [10]: l=[1,2,3] ...: l.append(l) после l.append(l) ссылка (reference) на список l будет добавлена в конец списка, что приводит к рекурсии: In [11]: l is l[3] Out[11]: True In [12]: id(l) == id(l[3]) Out[12]: True как это сделать правильно: In [14]: l.append(l[:]) In [15]: l Out[15]: [1, 2, 3, [1, 2, 3]] если вам нужен плоский (не вложенный) список: In [17]: l.extend(l) In [18]: l Out[18]: [1, 2, 3, 1, 2, 3] l[:] - создает копию списка в памяти: In [19]: l=[1,2,3] In [20]: l[:] is l Out[20]: False In [21]: id(l[:]) Out[21]: 179393864 In [22]: id(l) Out[22]: 197356744

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

#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)]

Ввод n элементов в одну строку

#python #список


Вот программа:

i = 1
k = 0
p = 0
n = int(input())
for i in range(1, n+1):
  a = int(input())
  if a % 2 == 0:
    k += 1
  if a % 2 != 0:
    p += 1
print(abs(k-p))


Элементы можно вводит в терминал только так:

3
1
2
3


А нужно вот так:

3
1 2 3 


Как это сделать?
    


Ответы

Ответ 1



можно разбить строку на числа: i = [int(a) for a in input().split()] пояснение: input() содержит введённую строку, .split() разбивает её по пробельным символам, создавая список полученных значений, дальше каждый элемент этого списка превращается в int, и добавляется в список i Это выражение аналогично следующему: i = [] for a in input().split(): i.append( int(a) ) результат: IN: "12 214 5 24 5" OUT: [12, 214, 5, 24, 5] использование в вашей программе: i = 1 k = 0 p = 0 n = int(input()) # не будет использоваться nums = [int(a) for a in input().split()] for a in nums: if a % 2 == 0: k += 1 if a % 2 != 0: p += 1 print(abs(k-p))

Ответ 2



input1 = list(map(int, '12 214 5 24 5'.split())) input2 = [int(a) for a in '11 213 4 23 5'.split()] print(input1) # [12, 214, 5, 24, 5] print(*input2) # 11 213 4 23 5 from itertools import chain print(*chain(input1, input2)) # 12 214 5 24 5 11 213 4 23 5

Ответ 3



Предлагаю такой вариант n=int(input()) a=map(int, input().split(maxsplit=n)) print(sum(a))

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

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

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


Допустим, у меня есть строка:    message = "Лебедьракщука"

Вместе с этим у меня есть ключ, указывающий на количество символов до каждого пробела:
   key = 634

Как мне создать список:    finally = ['Лебедь', 'рак', 'щука']
    


Ответы

Ответ 1



К примеру так: In [27]: message Out[27]: 'Лебедьракщука' In [28]: key Out[28]: [6, 3, 4] In [29]: def splitWords(word, key): ...: step = 0 ...: result = [] ...: for i in key: ...: result.append(word[step:i+step]) ...: step += i ...: return result ...: In [30]: splitWords(message, key) Out[30]: ['Лебедь', 'рак', 'щука'] По поводу key: Если он в таком формате, делаем так: In [1]: key = 634 In [2]: list(map(int, str(key))) Out[2]: [6, 3, 4]

Ответ 2



Можно воспользоваться RegEx: In [62]: key = 634 In [63]: key = list(map(int, str(key))) In [64]: key Out[64]: [6, 3, 4] import re In [22]: pat = ''.join(['(.{{{}}})'.format(k) for k in key]) In [23]: repl = ' '.join([r'\{}'.format(i) for i in range(1, len(key)+1)]) In [24]: pat Out[24]: '(.{6})(.{3})(.{4})' In [25]: repl Out[25]: '\\1 \\2 \\3' In [26]: re.sub(pat, repl, message) Out[26]: 'Лебедь рак щука' In [27]: re.sub(pat, repl, message).split() Out[27]: ['Лебедь', 'рак', 'щука'] PS но решение от @Alban мне нравится больше... Вот еще одно решение: In [57]: [message[sum(key[:i]) : sum(key[:i+1])] for i in range(len(key))] Out[57]: ['Лебедь', 'рак', 'щука'] Как это работает: In [73]: [print('{} : {}'.format(sum(key[:i]),sum(key[:i+1]))) for i in range(len(key))] 0 : 6 6 : 9 9 : 13

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

#java #строки #список


Есть строка с цифрами от 0 до 9, без пробелов. На выходе должен получиться список
int, при чем если после какой-то единицы стоит ноль, то такие ноль и единица должны
быть записаны в списке как 10. Таким образом не выходе должен получиться список из
чисел от 1 до 10. Как это сделать?
    


Ответы

Ответ 1



Извлечение чисел от 0 до 10 из потока циферь. Главное сформулировать условие, когда заканчивается одно число и начинается другое. Если на предыдущей итерации получена единица и сейчас перед нами ноль, то мы всё ещё находимся на том же самом числе (на десятке). В остальных случаях мы перешли на следующее число. Когда случился переход на следующее число, предыдущее надо вывести (поместить в массив) // чтобы просто переводить символы в числа/цифры public static Map CHAR2DIGIT = new HashMap() {{ put('0', 0); put('1', 1); put('2', 2); put('3', 3); put('4', 4); put('5', 5); put('6', 6); put('7', 7); put('8', 8); put('9', 9); }}; public static List numbers(String input) { List numbers = new ArrayList<>(); int number = -1; // сюда будем собирать очередное число. -1 когда находимся в самом начале потока и ещё не получено ни одной цифры for (int i = 0; i < input.length(); i++) { int digit = CHAR2DIGIT.get(input.charAt(i)); // очередная цифра if (digit != 0 || number != 1) { // условие перехода на следующее число if (number > -1) numbers.add(number); // вывод предыдущего number = 0; // сброс для расчёта нового числа } number = number * 10 + digit; // незамысловатая формула для сбора числа из его циферь } if (number > -1) numbers.add(number); // не забыть вывести последнее число после цикла return numbers; } public static void main(String[] args) { for (Integer n : numbers("1234567891001")) { System.out.println(n); } }

Ответ 2



По вашим условиям '0' тоже должен присутствовать (когда '0' в начале строки или не после '1'), то есть диапазон не от 1 до 10, а от 0 до 10: String str = "010320101"; int[] numbers = str.replaceAll("10", ":").chars().map(i -> i -= 48).toArray(); Результат: numbers[i]: 0 = 0 1 = 10 2 = 3 3 = 2 4 = 0 5 = 10 6 = 1 Дополнение: "должен получиться список" List numbers = str.replaceAll("10", ":").chars().mapToObj(i -> i -= 48) .collect(Collectors.toList());

Ответ 3



Можно сделать с использованием Java 8 Stream API: public void someMethod(){ String str = "1234567890"; List list = Arrays.stream(str.split("")).map(s -> Integer.valueOf(s)).collect(Collectors.toList()); list.replaceAll(i -> i==0?10:i); list.forEach(System.out::println); }

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

#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 г.

повторить строку N раз на bash

#linux #bash #список


Подскажите как повторить каждую строку текстового документа нужное кол-во раз. Есть
какая-нибудь простая и изящная команда на bash ? Спасибо
    


Ответы

Ответ 1



некоторые из множества вариантов, правда, использующие другие программы: $ sed 'p;p' файл $ perl -lpE 'say;say' файл $ awk '1;1;1' файл $ awk '{for(i=1;i<=3;i++)print}' файл а средствами программы bash не так изящно: $ while read line; do for i in {1..3}; do echo "$line"; done; done < файл каждый из приведённых примеров выведет утроенной каждую строку файла.

Ответ 2



n=5 # изменить на нужное к-во # cat file.txt | while read string; do while read string; do for i in $(seq 1 $n); do printf '%s\n' "$string" # здесь не обязательно printf '%s\n' достаточно echo done done < file.txt # поправил в соответствии с конструктивной критикой ну или чтобы изящно quantity=5 # Изменить на нужное количество awk '{for(i=1;i<=count;i++)print}' count=$quantity file.txt

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

Связный список, оператор -> (С++)

#cpp #visual_studio #список #односвязный_список


Есть код:

struct Element      //структура задающая элемент односвязного списка
{
    int data;       //информационное поле для хранения данных
    Element *next;  //указатель на следующий элемент
} *start, *current;

void create_list(int a)
{
    current = new Element;
    current->data = a;
    current->next = NULL;
    start = current;
}

void new_element(int a)
{
    Element *q;
    q = new Element;
    q->data = a;
    q->next = current->next;
    current->next = q;
}

void delete_element(int a)
{
    while (current->data != a)
    {
        current = current->next;
        if (current->data == a)
        {
            delete current;
        }
    }
}


Не совсем понял, что происходит в этих строчках:

current->next = NULL;


функции create_list(int)

и

q->data = a;
q->next = current->next;
current->next = q;


функции new_element(int)

Объясните, пожалуйста.
    


Ответы

Ответ 1



Первый - current->next = NULL; просто устанавливает элемент, на который указывает current, последним в списке - за ним (next) ничего нет. q->data = a; q->next = current->next; current->next = q; Это просто вставляет элемент после current - теперь новый элемент q указывает туда же, куда раньше указывал элемент, на который указывал current, а он теперь указывает на q. Вот примерный набросок - простите уж за отсутствие художественного таланта :) Видите? разорвали связь и воткнули туда новый элемент...

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

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

#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))

вторник, 28 января 2020 г.

Загрузка списка из 200MB файла отбирает больше 1GB памяти. Почему такой прирост?

#python #память #список


Есть текстовый файл list.txt, состоящий из строк вида:

name1
name2
name3
name4
name5
...


Файл на диске занимает 196 МБ.

При загрузке его следующим методом:

L = []
F = open('list.txt')
L = F.readlines()
F.close()


оперативная память, занимаемая процессом становится порядка 1,3 ГБ.

Помогите разобраться, почему такой прирост использования памяти относительно файла
на диске?
    


Ответы

Ответ 1



>>> sys.getsizeof('hello') 54 >>> sys.getsizeof('h') 50 >>> sys.getsizeof('hellohello') 59 >>> Вот пример из windows10 64 битная. Видно, что одна строка занимает 49 байт + 1байт на символ. Но! это ж UTF-8 строки и для кириллицы пойдет больше символов. sys.getsizeof('Вася') 82 >>> по формуле: 74 байта + 2 на символ. Теперь о затратах на хранение в списке. ЭТО на х64 винде: 40+8*количество_элементов байт. Пробуем сложить, считая что каждое имя ровно 5 символов: 16кк * ( (74 + 2*5) + 8) + 40 = 1 472 кк то есть ваши 1.3 Гига Что делать? 1) посмотрите массивы numpy - они экономнее и по памяти и быстрее в работе. Думаю, массив numpy будет примерно 300кк памяти, так как он почти "фортрановский" :-) 2) Измените алгоритм так, чтобы не хранить в памяти весь список. Как правило это удается. Например чтение из файла используя yield генераторы и т.д.

Замена элементов в листе по их индексу начиная с 1 а не 0

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


Есть лист

list_1 = ['a', 'b', 'c']


Значения должны быть заменены таким образом

list_1 = ['element_1', 'element_2', 'element_3']


Начиная с 1 а не 0

Я пробовала так сделать

list_1 = ['element_{}'.format(i) for i in range(i+1, len(list_1))]


или так

list_1 = ['element_{}'.format(i) for i in range(1, len(list_1))]


Но если в листе 1 элемент возвращается пустой лист

list_2 = ['a']

    


Ответы

Ответ 1



На выбор: list_1 = ['element_{}'.format(i+1) for i in range(len(list_1))] list_1 = ['element_{}'.format(i) for i in range(1, len(list_1)+1)]

Ответ 2



for i in range(len(list_1)): # Проходим циклом по номерам списка list_1[i] = 'element_' + str(i + 1) # элементу списка с текущим номером присваиваем номер + 1, в виде строки

Ответ 3



Мне кажется для данной задачи более уместно использовать enumerate(iterable, start=1): >>> res = [f"element_{i}" for i,x in enumerate(list_1, 1)] >>> print(res) ['element_1', 'element_2', 'element_3'] PS именно для этих целей и была создана функция enumerate() ;-)

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

Сортировка элементов (insertion sort) односвязного списка. си

#c #сортировка #указатели #список


Добрый день, 

Были заданы два задания: 


Создать односвязный список (список литературы);
На основе первого задания, сделать сортировку вставками по ISBN книг в порядке возрастания. 


Сам список отработал хорошо. Сортировку же реализовать не удаётся.
Вот наработки кода сортировки, есть ли хоть что-то близкое к истине?   

    element* insert_sorted(element *first, element *new_elem) {

    element *current = first;
    //element *insert = first;
    current = current->next; 
    element *temp;

    // element *next = first->next;
    // element *prev=NULL;
    // prev->next = first;

    // if(first==NULL){
    //     first = new_elem;
    // }
    while(current!=NULL){
        new_elem = first;
        while(new_elem!=current){
            if(new_elem->isbn > current->isbn){
                    temp = current->next;
                    current->next = new_elem;
                    new_elem->next = temp;

                    // first = next;
                    // temp = next;
            }
            else{
                new_elem = new_elem->next;
                    // end = next->next;
                    // next->next = new_elem;
                    // new_elem->next = end;

                    // prev = next;
                    // next = first->next;
            }
        }
        // else{
        //     prev = new_elem;
        //     new_elem = new_elem->next;
        // }
        // next = new_elem->next;
        // if (next == end){
        //     end = new_elem;
        }
    return first;
}


Код программы целиком: 

#include 
#include 
#include 

typedef struct _element element; 

typedef struct _list list;

struct _list {      
    element *first; 
    int count;      
};

struct _element
{
    char *title;
    char *author;
    int year;
    long long int isbn;
    element *next;
};

element* insert_sorted(element *first, element *new_elem) {
    /* HIER implementieren. */
    element *current = first;
    //element *insert = first;
    current = current->next; 
    element *temp;
    // element *next = first->next;
    // element *prev=NULL;
    // prev->next = first;

    // if(first==NULL){
    //     first = new_elem;
    // }
    while(current!=NULL){
        new_elem = first;
        while(new_elem!=current){
            if(new_elem->isbn > current->isbn){
                    temp = current->next;
                    current->next = new_elem;
                    new_elem->next = temp;

                    // first = next;
                    // temp = next;
            }
            else{
                new_elem = new_elem->next;
                    // end = next->next;
                    // next->next = new_elem;
                    // new_elem->next = end;

                    // prev = next;
                    // next = first->next;
            }
        }
        // else{
        //     prev = new_elem;
        //     new_elem = new_elem->next;
        // }
        // next = new_elem->next;
        // if (next == end){
        //     end = new_elem;
        }
    return first;
}

element *construct_element(char *title, char* author, int year, long long int isbn) {

    element *buch =  (element*) malloc (sizeof(element));
    buch->title = malloc(MAX_STR* sizeof(char));
    buch->author = malloc(MAX_STR* sizeof(char));
    strcpy(buch->title,title);
    strcpy(buch->author,author);
    buch->year = year;
    buch->isbn = isbn;
    buch->next = NULL;
    return buch;
}

void free_list(list *alist) {

    element* current;
    element* head = alist->first;

    free(alist);

    while((current = head) != NULL){
        head = head->next;

        free(current->title);
        free(current->author);
        free(current);
    }
}

void read_list(char* filename, list *alist) {
    element* new_elem;

    char title[MAX_STR];
    char author[MAX_STR];
    int year;
    long long int isbn;
    while(read_line(filename, title, author, &year, &isbn) == 0) {
        new_elem = construct_element(title, author, year, isbn);
        alist->first = insert_sorted(alist->first, new_elem);
        alist->count++;
    }
}

list* construct_list() {
    list *alist = malloc(sizeof(list));
    alist->first = NULL;
    alist->count = 0;
    return alist;
}

void print_list(list *alist) {
    printf("Meine Bibliothek\n================\n\n");
    int counter = 1;
    element *elem = alist->first;
    while (elem != NULL) {
        printf("Buch %d\n", counter);
        printf("\tTitel: %s\n", elem->title);
        printf("\tAutor: %s\n", elem->author);
        printf("\tJahr:  %d\n", elem->year);
        printf("\tISBN:  %lld\n", elem->isbn);
        elem = elem->next;
        counter++;
    }
}

int main() {
    list *alist = construct_list();
    read_list("buecherliste.txt", alist);
    print_list(alist);
    free_list(alist);
    return 0;
}

    


Ответы

Ответ 1



Вам не следует использовать имена, начинающиеся с подчеркивания, так как они зарезервированы за реализацией стандартных библиотек. Также совершенно нет никакой необходимости объявлять список в динамической памяти. Ниже приведена демонстрационная программа, которая сортирует список по возрастанию номеров ISBN. Надеюсь, она использует метод сортировки вставкой.:) Для наглядности я упростил определения и убрал из программы все лишнее, что не требуется конкретно для сортировки. Вам, естественно, потребуется нарастить "мясом" данный "скелет" метода. #include #include #include typedef struct element { unsigned long long int isbn; struct element *next; } element; typedef struct list { element *first; int count; } list; list construct_list() { list lst = { NULL, 0 }; return lst; } void push_front( list *lst, unsigned long long int isbn ) { element *item = malloc( sizeof( element ) ); if ( item ) { item->next = lst->first; item->isbn = isbn; lst->first = item; } } void print_list( const list *lst ) { for ( const element *current = lst->first; current; current = current->next ) { printf( "%lld ", current->isbn ); } } void sort_by_isbn( list *lst ) { if ( lst->first ) { element *current = lst->first->next; lst->first->next = NULL; while ( current ) { if ( current->isbn < lst->first->isbn ) { element *tmp = current; current = current->next; tmp->next = lst->first; lst->first = tmp; } else { element *first = lst->first; while ( first->next && !( current->isbn < first->next->isbn ) ) { first = first->next; } element *tmp = current; current = current->next; tmp->next = first->next; first->next = tmp; } } } } #define N 10 int main( void ) { list lst = construct_list(); srand( ( unsigned int )time( NULL ) ); for ( int i = 0; i < N; i++ ) push_front( &lst, rand() ); print_list( &lst ); printf( "\n" ); sort_by_isbn( &lst ); print_list( &lst ); printf( "\n" ); return 0; } Вывод программы может выглядеть следующим образом: 461971353 1686854524 262763134 1776774882 166562428 351823644 1662884659 155739745 669011733 1476766544 155739745 166562428 262763134 351823644 461971353 669011733 1476766544 1662884659 1686854524 1776774882

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

Объясните пожалуйста как работает данный код

#python #список #python_37


Объясните, пожалуйста, как работает этот код.  

Почему ['d'] на первом месте в списке x и почему повторяется ['a', 'b', 'c']?

x = [[]]*3

x[0].append('a')
x[1].append('b')
x[2].append('c')
x[0]=['d']

print(x)


stdout:

[['d'], ['a', 'b', 'c'], ['a', 'b', 'c']]

    


Ответы

Ответ 1



Если выражаться просто, то список - это некое хранилище ссылок. В Вашем примере, при умножении, новые списки не создаются. Вы размножаете ссылки. Поэтому после первой инструкции список содержит 3 ссылки на один и тот же объект списка. Проверить это можно с помощью оператора is: x = [[]] * 3 print(x[0] is x[1] is x[2]) # True Вот и получается, что Вы добавляете элементы в одни и те же списки: stdout: [['d'], ['a', 'b', 'c'], ['a', 'b', 'c']] ['d'] оказался на первом месте, так как Вы явно создали новый объект с помощью литералов и заменили ссылку в x[0]

четверг, 2 января 2020 г.

Перебор ключ-значение в 2-х и более словарях и запись совпадения в новый словарь через *args

#python #python_3x #список #словари


Имеется два словаря, нужно перебрать ключ-значение в обоих словарях.
Сравнить если одинаковые ключ-значения с помощью цикла for и параметра *args. Добавить
в новый словарь одинаковые найденные ключ-значения.

operator_one = { 2: 'break',
         1: 'pass',
         3: 'print',
         4: 'yield',
         5 :'try' ,
         }


operator_two = { 1: 'pass',
         2:'global',
         3: 'yield',
         4: 'print',
         5: 'try',
         }

def operator_important(farg, *args):
    """Перебор ключ-значения в двух словарях при помощи args и записи в новый словарь."""
    operator_main = dict()             # создание словаря и запись в перем
    print("vocabulary_one:", farg)     # вывод первого аргумента
    for key, value in args:            # перебор ключ-значение в обоих словарях
        print("vocabulary_two:", arg)  # вывод второго аргумента
        if key in args and value == args[key]: # если ключ-значение равно аргументу
ключ-значение, то создаем новый словарь с ключом и значение
            operator_main[key] = value # добавляем в нов. словарь найденное  ключ-значение,
которое совпало


Ошибка: 


  ValueError: too many values to unpack (expected 2)

    


Ответы

Ответ 1



У меня вот так получилось: operator_one = {2: 'break', 1: 'pass', 3: 'print', 4: 'yield', 5: 'try', } operator_two = {1: 'pass', 2: 'global', 3: 'yield', 4: 'print', 5: 'try', } operator_three = {1: 'pass', 2: 'global', 3: 'yield', 4: 'print', 5: 'try', } def operator_important(*args: dict): operator_main = dict() # Создаем пустой словарь for key, value in args[0].items(): # Для ключа и значения из первого словаря... check = True # Устанавливаем флаг проверки в значение "Истина" for i in range(1, len(args)): # Проверяем все словари на совпадение if key not in args[i] or value != args[i][key]: # Если ключ отсутствует в другом словаре # или его значение отлично от проверяемого check = False # Устанавливаем флаг в значение "Ложь" break # И прерываем проверку ключа if check: # Если флаг сохранил значение "Истина" (То есть ключ присутствует во всех проверяемых словарях # и значения ключа во всех словарях равны operator_main[key] = value # Добавляем ключ и значение в новый словарь return operator_main print(operator_important(operator_one, operator_two, operator_three)) Немного упростил функцию: def operator_important(*args: dict): operator_main = dict() # Создаем пустой словарь for key, value in args[0].items(): # Для ключа и значения из первого словаря... for i in range(1, len(args)): # Проверяем все словари на совпадение if key not in args[i] or value != args[i][key]: # Если ключ отсутствует в другом словаре # или его значение отлично от проверяемого break # Прерываем проверку ключа else: # Если цикл не прерывался (То есть ключ присутствует во всех проверяемых словарях # и значения ключа во всех словарях равны operator_main[key] = value # Добавляем ключ и значение в новый словарь return operator_main

Ответ 2



Вы можете послать параметры в функцию с помощью распаковки, привожу возможные варианты для это функции: operator_one = { 2: 'break', 1: 'pass', 3: 'print', 4: 'yield', 5 :'try' , } operator_two = { 1: 'pass', 2:'global', 3: 'yield', 4: 'print', 5: 'try', } def my_dict(d1, d2): d3 = dict() for k in d1: if k in d2 and d1[k] == d2[k]: d3[k] = d1[k] return d3 print (my_dict(*(operator_one, operator_two))) print (my_dict(operator_one, *(operator_two, ))) print (my_dict(operator_one, operator_two, *())) # {1: 'pass', 5: 'try'} Если вы хотите посылать неограниченное количество словарей в функцию то можно так: operator_three = { 1: 'qwerty', 2:'global', 3: 'yield', 4: 'print', 5: 'try', } def my_dict(*d_tuple): w = [x.items() for x in d_tuple] first = w[0] other = w[1:] res = [] for f in first: s = 1 for elem in other: if f not in elem: s = 0 break if s: res.append(f) return dict(res) print (my_dict(*(operator_one, operator_two, operator_three))) # {5: 'try'}

Ответ 3



Ошибка в комманде for key, value in args: # перебор ключ-значение в обоих словарях так как args - кортеж из одного элемента (словаря, заданного как параметр). И так, вместо args нужно везде писать args[0] (и в цикле for добавить ещё .items()): for key, value in args[0].items(): # перебор ключ-значение в обоих словарях print("vocabulary_two:", args[0]) # вывод второго аргумента if key in args and value == args[0][key]: # если ключ-значение равно аргументу ключ-значение, то создаем новый словарь с ключом и значение Но луже вашу функцию слишком изменить - исключить параметр farg, т.к оба параметра могут быть в кортежи args: def operator_important(*args): """Перебор ключ-значения в двух словарях при помощи args и записи в новый словарь.""" operator_main = dict() # создание словаря и запись в перем print("vocabulary_one:", args[0]) # вывод первого аргумента for key, value in args[0].items(): # перебор ключ-значение в обоих словарях print("vocabulary_two:", args[1]) # вывод второго аргумента if key in args and value == args[key]: # если ключ-значение равно аргументу ключ-значение, то создаем новый словарь с ключом и значение operator_main[key] = value # добавляем в нов. словарь найденное ключ-значение, которое совпало

Python: разбить список на список списков, по элементу-разделителю

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


Python 3.2.
Есть список lst, в котором есть значения вперемешку с элементами-разделителями. Например,
["spam", "ham", None, "eggs", None, None, "bacon"]. Хочу получить список списков, разбив
lst по разделителю sep = None, т.е., получить [["spam", "ham"], ["eggs"], ["bacon"]].
Полистал стандартную библиотеку, но ничего похожего не нашел. На PyPi искать сложно,
быстрый пробег тоже ничего не дал. Наглая попытка проэксплуатировать str.split, разумеется,
провалилась с TypeError.
Посоветуйте, пожалуйста, более красивое решение, чем вот этот вырвиглазный монстр.
Не хочу ощущать себя Франкенштейном.
from functools import reduce

# Fugly.
def split_on(sep, lst):
    """
    Given an iterable `lst`, split it into iterable of lists by `sep`.

    >>> list(split_on(0, [1, 2, 3, 0, 4, 5, 0, 0, 6]))
    [[1, 2, 3], [4, 5], [6]]
    """
    s = sep if hasattr(sep, "__call__") else lambda x: x == sep
    return filter(lambda sublist: len(sublist) > 0,
                  reduce(lambda x, elem: x + [[]] if elem == sep
                                                else x[:-1] + [x[-1] + [elem]],
                         lst, [[]]))
    


Ответы

Ответ 1



Судя по всему, функциональное программирование оставило на вас серьезный отпечаток :) Сразу отмечу, что семантика split для случая вашего примера подразумевает возврат [["spam", "ham"], ["eggs"], [], ["bacon"]]. Это так, поскольку между None и None с точки зрения разделителей располагается пустой список. Так вот, решений можно придумать несколько. Наиболее explicit вариант подразумевает что-то в следующем духе: def split_on(what, delimiter = None): splitted = [[]] for item in what: if item == delimiter: splitted.append([]) else: splitted[-1].append(item) return splitted Понятно, что это решение работает с точностью до контракта функции касательно работы в случае пустого списка - [] и списка, состоящего только из разделителя - [None]. Я определил этот контракт следующим образом: [ ] -> [[ ]], [None] -> [[], []]. Для первого случая контракт довольно спорный. Во втором же случае результат получается, поскольку слева и справа от разделителя по сути расположены пустые последовательности. В случае, если вы захотите изменить это поведение, то модифицировать метод не должно составить особого труда. Пример использования: list1 = ["spam", "ham", None, "eggs", None, None, "bacon"] list2 = [] list3 = [None] list4 = ["eggs"] print split_on(list1) print split_on(list2) print split_on(list3) print split_on(list4) # Результат: [['spam', 'ham'], ['eggs'], [], ['bacon']] [[]] [[], []] [['eggs']] Из альтернативных вариантов - можно написать аналогичный предложенной функции генератор с yield'ами и, думаю, что можно придумать решение, разбивая предложенную итерабельную последовательность на группы, а дальше объединяя результаты путем groupby из itertools. Правда, мне кажется, что очевидность этих решений по сравнению с предложенным выше методом будет несколько хуже.

Ответ 2



m=["spam","ham","N","edg","N","N","back"] q=0 i=0 t=list(([],)*m.count("N")) for x in m: if x=="N": q=1 continue if q==1: i=i+1 t[i]=[] t[i].append(x) print(i,"---",t[i]) z=input() ============================= 0 --- ['spam'] 0 --- ['spam', 'ham'] 1 --- ['edg'] 2 --- ['back'] t=[['spam', 'ham'], ['edg'], ['back']]

вторник, 31 декабря 2019 г.

Поиск слова по букве, и замена буквы

#python #алгоритм #python_3x #список


Нужно найти в списке слов все слова на букву "в", и заменить букву "в"  на букву
"а" во всех словах. Как это сделать, без разбивания каждого слова на буквы и замены
по индексу. 
Пример:

Вход:

a=['рука', 'нож', 'ведро', 'Неаполь', 'Виктория', 'материк']


Выход:

a=['рука', 'нож', 'аедро', 'Неаполь', 'аиктория', 'материк']

    


Ответы

Ответ 1



Для списка: import re In [143]: print(a) ['рука', 'нож', 'ведро', 'Неаполь', 'Виктория', 'материк', 'бровь'] In [144]: new = [re.sub(r'^в', r'а', word, flags=re.U|re.I) for word in a] In [145]: print(new) ['рука', 'нож', 'аедро', 'Неаполь', 'аиктория', 'материк', 'бровь'] # ^ Для строки: import re s = 'Нужно найти в списке слов все слова на букву "в", и заменить букву "в" на букву "а" во всех словах. Как ето сделать, без разбивания каждого слова на буквы и замены по индексу. Большое Спасибо!' new = re.sub(r'\bв', r'X', s, flags=re.UNICODE) print(new) Результат: Нужно найти X списке слов Xсе слова на букву "X", и заменить букву "X" на букву "а" Xо Xсех словах. Как ето сделать, без разбивания каждого слова на б уквы и замены по индексу. Большое Спасибо!

Ответ 2



Чтобы большую и маленькую "в" заменить на маленькую "а" в каждом слове в списке (не только в начале слова): table = str.maketrans("вВ", "аа") result = [word.translate(table) for word in a] Или, не создавая новый список: for i, word in enumerate(a): a[i] = word.translate(table) Чтобы заменить "в" только в начале слова: result = ["а" + word[1:] for word in a if word[0] in "вВ"]) Или, не создавая новый список: for i, word in enumerate(a): if word[0] in "вВ": a[i] = "а" + word[1:] Если буква у вас может более одной Unicode code point занимать, к примеру "ё" в NFD форме (буквальное сравнение): if word.startswith(letter): a[i] = replacement + word[len(letter):]

Ответ 3



replace = lambda s: 'а%s'%s[1:] if s.startswith('в') else s list(map(replace, a))

понедельник, 30 декабря 2019 г.

Нахождение max() и min() в столбце CSV файла

#python #python_3x #список #матрицы #csv


Дан файловый объект .txt, в котором данные приведены как числа:


  Rosneft,07/19/06,00:00,220.32,220.32,203.03,203.95,51774,0


Таких данных около 2 тыс. и все они записаны в файле с новой строки.
Нужно найти максимальную и минимальную цену и ее дату в файле.  

file = open('file.txt') # Открыть файл
for line in file: # Пройти циклом 
    new_line1 = line.split(',') #разделить строки по запятым в new_line1
    new_file1 = new_line1[4:6] # срезать нужные строки  


И на этом логика выполнения задачи зашла в тупик. Хотелось бы понять эту логику в
примерах как с ф-цией min() и max(), так и без неё.
    


Ответы

Ответ 1



Решение без использования доп. модулей: Файл с данными (C:\Temp\data.csv): Rosneft,07/19/06,00:00,220.32,220.32,203.03,203.95,51774,0 Rosneft,07/20/06,00:00,230.33,230.34,230.35,230.36,56544,0 Rosneft,07/21/06,00:00,210.33,210.34,210.35,210.36,50344,0 Решение: filename = r'C:\Temp\data.csv' data = [] with open(filename) as f: for line in f: tmp = line.split(',') tmp[3:] = list(map(float, tmp[3:])) data.append(tmp) def transpose(matrix): return list(zip(*matrix)) def get_min_idx(data, col_idx=0): return min(range(len(data)), key=transpose(data)[col_idx].__getitem__) def get_max_idx(data, col_idx=0): return max(range(len(data)), key=transpose(data)[col_idx].__getitem__) print('Min:\t', data[get_min_idx(data, col_idx=3)]) print('Max:\t', data[get_max_idx(data, col_idx=3)]) Результат: Min: ['Rosneft', '07/21/06', '00:00', 210.33, 210.34, 210.35, 210.36, 50344.0, 0.0] Max: ['Rosneft', '07/20/06', '00:00', 230.33, 230.34, 230.35, 230.36, 56544.0, 0.0]

Ответ 2



Для обработки табличных (2D) данных идеально подходит модуль Pandas. Пример: создадим тестовый файл похожей структуры, в качестве данных возьмем котирови Apple начиная с 2001-го года (4490 строк) import pandas as pd # pip install pandas from pandas_datareader.data import DataReader # pip install pandas-datareader df = DataReader('AAPL', 'yahoo', '2001-01-01', '2018-11-06').reset_index() df.to_csv('c:/temp/data.csv', index=False) Несколько строк из файла: Date,High,Low,Open,Close,Volume,Adj Close 2001-01-02,1.0892857313156128,1.0401785373687744,1.0625,1.0625,113078000.0,0.713999330997467 2001-01-03,1.1919642686843872,1.03125,1.0357142686843872,1.1696428060531616,204268400.0,0.7859991192817688 2001-01-04,1.3214285373687744,1.2008928060531616,1.2957571744918823,1.21875,184849000.0,0.818999171257019 2001-01-05,1.2410714626312256,1.1473214626312256,1.2098214626312256,1.1696428060531616,103089000.0,0.7859991192817688 2001-01-08,1.2131643295288086,1.1383928060531616,1.2098214626312256,1.1830357313156128,93424800.0,0.7949992418289185 Решение: import pandas as pd df = pd.read_csv(r'c:/temp/data.csv') поиск строк с наименьшим и наибольшим значением в поле Adj Close: In [27]: print(df.nsmallest(1, ['Adj Close'])) Date High Low Open Close Volume Adj Close 573 2003-04-17 0.946429 0.908571 0.942857 0.937143 154064400.0 0.629759 In [28]: print(df.nlargest(1, ['Adj Close'])) Date High Low Open Close Volume Adj Close 4466 2018-10-03 233.470001 229.779999 230.050003 232.070007 28654800.0 232.070007 TOP 5 значений: In [29]: print(df.nlargest(5, ['Adj Close'])) Date High Low Open Close Volume Adj Close 4466 2018-10-03 233.470001 229.779999 230.050003 232.070007 28654800.0 232.070007 4465 2018-10-02 230.000000 226.630005 227.250000 229.279999 24788200.0 229.279999 4445 2018-09-04 229.179993 226.630005 228.410004 228.360001 27390100.0 228.360001 4467 2018-10-04 232.350006 226.729996 230.779999 227.990005 32042000.0 227.990005 4444 2018-08-31 228.869995 226.000000 226.509995 227.630005 43340100.0 227.630005

Ответ 3



Логика такова: line="Rosneft,07/19/06,00:00,220.32,220.32,203.03,203.95,51774,0" elems=line.split(',') date=elems[1] prices = list(map(float,elems[3:7])) print("На {} максимум: {}, минимум: {}".format(date, max(prices), min(prices))) На выходе: На 07/19/06 максимум: 220.32, минимум: 203.03