Основы, необходимые для создания карты в D3js [duplicate]

Каковы варианты клонирования или копирования списка в Python?

В 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. Почему это?

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))
  1. Это опасно, особенно если вы оцениваете что-то из источника, которому вы не доверяете.
  2. Это не надежный, если подэлемент, который вы копируете, не имеет представления, которое может быть доказано для воспроизведения эквивалентного элемента.
  3. Он также менее эффективен.

В 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
28
задан Belphegor 26 August 2014 в 13:37
поделиться

5 ответов

Если вы работаете в браузере, вы не можете загружать локальные файлы .

Но довольно просто запустить dev-сервер, в командной строке, просто cd в каталог с вашими файлами, затем:

python -m SimpleHTTPServer

(или python -m http.server с помощью python 3)

Теперь в вашем браузере перейдите к localhost:3000 (или :8000 или что-то, что показано на командной строке).


Следующие используются для работы в более старых версиях d3:

var json = {"my": "json"};
d3.json(json, function(json) {
    root = json;
    root.x0 = h / 2;
    root.y0 = 0;
});
29
ответ дан mb21 21 August 2018 в 07:03
поделиться
  • 1
    Может быть сделано с последним Firefox. – Amit 20 September 2014 в 22:15
  • 2
    Не могли бы вы немного объяснить свой код ... как бы я пошел от этого d3.json(filename, function(error, data) {...} (Должен ли я задать отдельный вопрос?) – Ismail Moghul 11 October 2014 в 00:13
  • 3
    Я бы сказал прямо, что код этого ответа неверен, за исключением 13 upvotes. d3.json берет url как свой первый аргумент, а не объект json. Ditto jQuery's $. Get метод. Если json уже определен в файле, нет необходимости выдавать запрос ajax через d3.json или $.get; просто ссылайтесь на переменную напрямую. Или я что-то пропустил здесь, чтобы объяснить 13 авитаминов? – James Conkling 18 September 2015 в 01:31
  • 4
    @JamesConkling переменная - это не то же самое, что файл. но да, вы можете поместить первую строку в мой пример в свой собственный файл javascript, и это тоже работает. – mb21 18 September 2015 в 09:58
  • 5
    @ mb21, да, и в этом случае d3.json() берет строку, представляющую путь к файлу. В случае no , если d3.json() принимает в качестве первого аргумента объект JSON (или что-то другое, кроме строки). см. здесь . – James Conkling 20 September 2015 в 18:29

Я использовал этот

d3.json("graph.json", function(error, xyz) {
    if (error) throw error;
    // the rest of my d3 graph code here
    }

, чтобы вы могли ссылаться на ваш json-файл, используя переменную xyz, а graph - это имя моего локального json-файла

0
ответ дан Aakanksha Choudhary 21 August 2018 в 07:03
поделиться

Добавляя к предыдущим ответам, проще использовать HTTP-сервер, предоставляемый большинством машин Linux / Mac (только с установленным python).

Выполните следующую команду в корне вашего проекта

python -m SimpleHTTPServer

Затем вместо доступа к file://.....index.html откройте ваш браузер на http://localhost:8080 или в порту, предоставляемом при запуске сервера. Таким образом браузер заставит все файлы в вашем проекте не блокироваться.

6
ответ дан bigsolom 21 August 2018 в 07:03
поделиться

Вы не можете легко читать локальные файлы, по крайней мере, не в Chrome, а, возможно, и в других браузерах.

Простейшим обходным путем является простое включение данных JSON в вашем файле сценария, а затем просто избавиться от вашего вызова d3.json и сохранить код в обратном вызове, который вы передаете ему.

Тогда ваш код будет выглядеть следующим образом:

json = { ... };

root = json;
root.x0 = h / 2;
root.y0 = 0;
... 
1
ответ дан Kenny Evitt 21 August 2018 в 07:03
поделиться

http://bl.ocks.org/eyaler/10586116 См. этот код, это чтение из файла и создание графика. У меня также была та же проблема, но позже я выяснил, что проблема была в json-файле, который я использовал (дополнительная запятая). Если вы получаете нуль, попробуйте напечатать ошибку, которую вы получаете, как это может быть.

d3.json("filename.json", function(error, graph) {
  alert(error)
})

Это работает в firefox, в хром как-то его не печатает ошибку.

7
ответ дан Surendra Pratap 21 August 2018 в 07:03
поделиться
Другие вопросы по тегам:

Похожие вопросы: