Каковы варианты клонирования или копирования списка в Python?
blockquote>В Python 3 мелкая копия может быть выполнена с помощью:
a_copy = a_list.copy()
В Python 2 и 3 вы можете получить мелкую копию с полным фрагментом оригинала:
a_copy = a_list[:]
Объяснение
Существует два семантических способа копирования списка. Неглубокая копия создает новый список тех же объектов, глубокая копия создает новый список, содержащий новые эквивалентные объекты.
Короткая копия списка
Неглубокая копия копирует только сам список, который является контейнером ссылок на объекты в списке. Если объекты, содержащиеся в них, являются изменяемыми и один из них изменен, это изменение будет отражено в обоих списках.
Существуют разные способы сделать это в Python 2 и 3. Пути Python 2 также будут работать в Python 3.
Python 2
В Python 2 , идиоматический способ создания мелкой копии списка состоит из полного фрагмента оригинала:
a_copy = a_list[:]
Вы также можете выполнить одно и то же, передав список через конструктор списка,
a_copy = list(a_list)
, но использование конструктора менее эффективно:
>>> timeit >>> l = range(20) >>> min(timeit.repeat(lambda: l[:])) 0.30504298210144043 >>> min(timeit.repeat(lambda: list(l))) 0.40698814392089844
Python 3
В Python 3 списки получают метод
list.copy
:a_copy = a_list.copy()
В Python 3.5:
>>> import timeit >>> l = list(range(20)) >>> min(timeit.repeat(lambda: l[:])) 0.38448613602668047 >>> min(timeit.repeat(lambda: list(l))) 0.6309100328944623 >>> min(timeit.repeat(lambda: l.copy())) 0.38122922903858125
Создание другого указателя делает not сделать копию
Используя new_list = my_list, тогда изменяет new_list каждый раз, когда изменяется my_list. Почему это?
blockquote>
my_list
- это просто имя, которое указывает на фактический список в памяти. Когда вы скажетеnew_list = my_list
, что вы не делаете копию, вы просто добавляете другое имя, указывающее на этот исходный список в памяти. У нас могут быть подобные проблемы, когда мы делаем копии списков.>>> l = [[], [], []] >>> l_copy = l[:] >>> l_copy [[], [], []] >>> l_copy[0].append('foo') >>> l_copy [['foo'], [], []] >>> l [['foo'], [], []]
Список - это всего лишь массив указателей на содержимое, поэтому мелкая копия просто копирует указатели, поэтому у вас есть два разных списка, но они имеют одинаковое содержимое. Чтобы сделать копии содержимого, вам нужна глубокая копия.
Глубокие копии
Чтобы сделать глубокую копию списка в Python 2 или 3, используйте
deepcopy
в модулеcopy
:import copy a_deep_copy = copy.deepcopy(a_list)
Чтобы продемонстрировать, как это позволяет нам создавать новые под-списки:
>>> import copy >>> l [['foo'], [], []] >>> l_deep_copy = copy.deepcopy(l) >>> l_deep_copy[0].pop() 'foo' >>> l_deep_copy [[], [], []] >>> l [['foo'], [], []]
Итак, мы видим, что глубокий скопированный список - это совсем другой список из оригинала. Вы можете перевернуть свою собственную функцию, но не надо. Вероятно, вы создадите ошибки, которых иначе не было бы, используя функцию глубокой печати стандартной библиотеки.
Не использовать
eval
Вы можете видеть, что это используется как способ to deepcopy, но не делайте этого:
problematic_deep_copy = eval(repr(a_list))
- Это опасно, особенно если вы оцениваете что-то из источника, которому вы не доверяете.
- Это не надежный, если подэлемент, который вы копируете, не имеет представления, которое может быть доказано для воспроизведения эквивалентного элемента.
- Он также менее эффективен.
В 64-битном Python 2.7:
>>> import timeit >>> import copy >>> l = range(10) >>> min(timeit.repeat(lambda: copy.deepcopy(l))) 27.55826997756958 >>> min(timeit.repeat(lambda: eval(repr(l)))) 29.04534101486206
на 64-битном Python 3.5:
>>> import timeit >>> import copy >>> l = list(range(10)) >>> min(timeit.repeat(lambda: copy.deepcopy(l))) 16.84255409205798 >>> min(timeit.repeat(lambda: eval(repr(l)))) 34.813894678023644
Вы должны предоставить доступ к root из localhost. Проверьте эту помощь ubuntu
У меня возникла эта проблема сегодня при установке SugarCRM (бесплатный CRM).
Системе не удалось подключиться к базе данных с помощью пользователя root. Я мог окончательно войти в систему как root из консоли ... так в чем была проблема?
Я узнал, что в моей ситуации я получал точно такую же ошибку, но это было потому, что был отправлен пароль к mysql непосредственно из данных $_POST
, другими словами, символ <
из моего пароля был отправлен в mysql как <
, что означает, что пароль был неправильным.
Все остальное не помогло немного. Список пользователей в mysql был правильным, включая анонимного пользователя (который появляется после корневых записей.)
WHERE
, которое вы показываете здесь, сбросит пароль ВСЕХ пользователей, у которых их нет. Не может быть только пользователь root (т. Е. WHERE User = 'root'
?)
– Alexis Wilke
9 August 2014 в 05:13
Из моего ответа здесь , подумал, что это может быть полезно:
Я попробовал много шагов, чтобы устранить эту проблему. Существует так много источников для возможных решений этой проблемы, что трудно отфильтровать смысл от бессмыслицы. Наконец, я нашел хорошее решение здесь :
Шаг 1: Идентифицировать версию базы данных
$ mysql --version
Вы увидите такой вывод с MySQL:
$ mysql Ver 14.14 Distrib 5.7.16, for Linux (x86_64) using EditLine wrapper
Или выводите как это для MariaDB:
mysql Ver 15.1 Distrib 5.5.52-MariaDB, for Linux (x86_64) using readline 5.1
Обратите внимание, какая база данных и какая версия вы используете, поскольку вы будете использовать их позже. Затем вам нужно остановить базу данных, чтобы вы могли получить к ней доступ вручную.
Шаг 2: Остановка сервера базы данных
Чтобы изменить пароль root, вам необходимо закрыть сервер базы данных
Вы можете сделать это для MySQL с помощью:
$ sudo systemctl stop mysql
И для MariaDB с:
$ sudo systemctl stop mariadb
Шаг 3: Перезапуск сервера базы данных без Проверка прав доступа
Если вы запустите MySQL и MariaDB без загрузки информации о привилегиях пользователей, это позволит вам получить доступ к командной строке базы данных с правами root без предоставления пароля. Это позволит вам получить доступ к базе данных, не зная об этом.
Для этого вам необходимо остановить загрузку базы данных таблицами грантов, в которых хранятся данные о привилегиях пользователя.
Запустите базу данных без загрузки таблиц грантов или создания сетей:
$ sudo mysqld_safe --skip-grant-tables --skip-networking &
Амперсанд в конце этой команды заставит этот процесс работать в фоновом режиме, чтобы вы могли продолжать использовать ваш терминал.
Теперь вы можете подключиться к базе данных как пользователь root, что не должно попросите пароль.
$ mysql -u root
Вместо этого вы сразу увидите приглашение оболочки базы данных.
MySQL Prompt
Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
mysql>
MariaDB Prompt
Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
MariaDB [(none)]>
Теперь, когда у вас есть root-доступ, вы можете изменить пароль root.
Шаг 4: Изменение корневого пароля
mysql> FLUSH PRIVILEGES;
Теперь мы можем реально изменить пароль root.
Для MySQL 5.7.6 и новее, а также для MariaDB 10.1.20 и новее используйте следующую команду:
mysql> ALTER USER 'root'@'localhost' IDENTIFIED BY 'new_password';
Для MySQL 5.7.5 и старше а также MariaDB 10.1.20 и старше, используйте:
mysql> SET PASSWORD FOR 'root'@'localhost' = PASSWORD('new_password');
Обязательно замените new_password
с вашим новым паролем по выбору.
Примечание. Если команда ALTER USER
не работает, это обычно указывает на большую проблему. Тем не менее, вы можете попробовать UPDATE ... SET
сбросить пароль root.
[ВАЖНО] Это конкретная строка, которая исправила мою конкретную проблему:
mysql> UPDATE mysql.user SET authentication_string = PASSWORD('new_password') WHERE User = 'root' AND Host = 'localhost';
Не забудьте перезагрузить таблицы предоставления после этого.
В любом случае вы должны увидеть подтверждение того, что команда была успешно выполнена.
Query OK, 0 rows affected (0.00 sec)
Пароль был изменен , поэтому теперь вы можете остановить ручной экземпляр сервера базы данных и перезагрузить его, как и раньше.
Шаг 5: Перезапустите сервер баз данных Обычно
В учебное пособие приводятся некоторые дополнительные шаги для перезапуска базы данных, но единственной частью, которую я использовал, было следующее:
Для MySQL используйте: $ sudo systemctl start mysql
Для MariaDB используйте:
$ sudo systemctl start mariadb
Теперь вы можете подтвердить, что новый пароль был применен правильно, выполнив:
$ mysql -u root -p
Теперь команда должна запросить новый пароль. Введите его, и вы должны получить доступ к приглашению базы данных, как ожидалось.
Заключение
Теперь у вас есть административный доступ к серверу MySQL или MariaDB. Убедитесь, что новый корневой пароль, который вы выбрали, прочный и безопасный и сохраните его в надежном месте.
Я решил эту проблему, удалив пустых пользователей, созданных MySQL. У меня есть только пользователь root и мой собственный пользователь. Я удалил остальные.
проверьте, что вы вводите пустое место в пароле.
Я много гулял, но не нашел определенного ответа на мою проблему. Я использовал KeyPass для создания надежного пароля и мог успешно использовать его в workbench mysql для подключения, но не из командной строки. Поэтому я сменил psw на простой, и он работал в командной строке. Мне удалось создать надежный пароль, который смог подключиться от терминала. Поэтому я советую, сначала попробуйте с легким паролем, прежде чем пытаться все это делать.
Я запускал UT, и я начал получать сообщения об ошибках. Я не знаю, в чем проблема. Но когда я изменил свой стиль кодировки в INTELLIJ на UTF8, он снова начал работать.
доступ запрещен для пользователя 'root' @ 'localhost' (с использованием пароля yes) hibernate
blockquote >это мой URL-адрес db.url = jdbc: mysql: // localhost: 3306 / somedb? useUnicode = true & amp; connectionCollation = utf8_general_ci & amp; characterSetResults = utf8 & amp; characterEncoding = utf8
попробуйте использовать root
, например ..
mysql -uroot
, после чего вы можете проверить разные пользователи и хосты после входа в систему с помощью
select user,host,password from mysql.user;
Обновить пустой пароль в таблице mysql.user mysql
use mysql;
select host,user,password from mysql.user;
update mysql.user set password = PASSWORD('123456') where password = '';
flush privileges;
WHERE
, которое вы показываете здесь, сбросит пароль ВСЕХ пользователей, у которых их нет. Не может быть только пользователь root (т. Е. WHERE User = 'root'
?)
– Alexis Wilke
9 August 2014 в 05:14
Я столкнулся с такой же ошибкой после обновления сервера MySQL с 5.1.73 до 5.5.45. Есть еще один способ исправить эту ошибку.
В моем случае я смог подключиться к MySQL, используя пароль root, но MySQL активно отказывался от GRANT PRIVILEGES любому пользователю,
mysql -u root -p
, затем введите свой пароль root MySQL; use mysql;
mysql.user
есть только одна запись для root, позволяющая подключаться только с localhost
(это было в моем случае), но по умолчанию для root должны быть две записи , один для localhost
и другой для 127.0.0.1
; Host='127.0.0.1'
, если ее нет; SET @s = CONCAT('INSERT INTO mysql.user SELECT ',
REPLACE((SELECT GROUP_CONCAT(COLUMN_NAME)
FROM INFORMATION_SCHEMA.COLUMNS
WHERE TABLE_NAME = 'user' AND TABLE_SCHEMA = 'mysql')
,"Host","'127.0.0.1'"),
' FROM mysql.user WHERE User="root"');
PREPARE stmt FROM @s;
EXECUTE stmt;
mysql_upgrade -u -p
, чтобы убедиться, что все в порядке. Мое приложение использует Mura CMS, и я столкнулся с этой проблемой. Однако решением было несоответствие пароля между моим локальным сервером mysql и паролем в файлах конфигурации. Как только я их синхронизировал, он работал.