Helpex - Trao đổi & giúp đỡ Đăng nhập
88

Tôi có một chương trình Python hoạt động với từ điển rất nhiều. Tôi phải tạo ra các bản sao của từ điển hàng ngàn lần. Tôi cần một bản sao của cả khóa và nội dung liên quan. Bản sao sẽ được chỉnh sửa và không được liên kết với bản gốc (ví dụ: thay đổi trong bản sao không được ảnh hưởng đến bản gốc.)

Khóa là Chuỗi, Giá trị là Số nguyên (0/1).

Tôi hiện đang sử dụng một cách đơn giản:

newDict = oldDict.copy()

Hồ sơ Mã của tôi cho thấy rằng hoạt động sao chép mất phần lớn thời gian.

Có những lựa chọn thay thế nhanh hơn cho dict.copy()phương pháp? Điều gì sẽ nhanh nhất?

88 hữu ích 5 bình luận 81k xem chia sẻ
62

Nhìn vào nguồn C cho các dicthoạt động của Python , bạn có thể thấy rằng chúng thực hiện một bản sao khá ngây thơ (nhưng hiệu quả). Về cơ bản, nó thực hiện một cuộc gọi đến PyDict_Merge:

PyDict_Merge(PyObject *a, PyObject *b, int override)

Điều này thực hiện kiểm tra nhanh những thứ như nếu chúng là cùng một đối tượng và nếu chúng có các đối tượng trong đó. Sau đó, nó thực hiện thay đổi kích thước / phân bổ một lần hào phóng cho lệnh chính và sau đó sao chép từng phần tử một. Tôi không thấy bạn nhận được nhanh hơn nhiều so với tích hợp copy().

62 hữu ích 1 bình luận chia sẻ
54

Dict.copy nhanh hơn, như bạn nói.

[utdmr@utdmr-arch ~]$ python -m timeit -s "d={1:1, 2:2, 3:3}" "new = d.copy()"
1000000 loops, best of 3: 0.238 usec per loop
[utdmr@utdmr-arch ~]$ python -m timeit -s "d={1:1, 2:2, 3:3}" "new = dict(d)"
1000000 loops, best of 3: 0.621 usec per loop
[utdmr@utdmr-arch ~]$ python -m timeit -s "from copy import copy; d={1:1, 2:2, 3:3}" "new = copy(d)"
1000000 loops, best of 3: 1.58 usec per loop
54 hữu ích 5 bình luận chia sẻ
12

Bạn có thể cung cấp một mẫu mã để tôi có thể thấy cách bạn đang sử dụng copy () và trong bối cảnh nào không?

Bạn đã có thể sử dụng

new = dict(old)

Nhưng tôi không nghĩ nó sẽ nhanh hơn.

12 hữu ích 0 bình luận chia sẻ
3

Tùy thuộc vào những thứ bạn để lại cho đầu cơ, bạn có thể muốn bọc từ điển gốc và thực hiện một loại sao chép trên ghi.

"Bản sao" sau đó là một từ điển tìm kiếm nội dung trong từ điển "cha mẹ", nếu nó không có khóa --- nhưng tự sửa đổi nội dung.

Điều này giả định rằng bạn sẽ không sửa đổi bản gốc và việc tra cứu thêm sẽ không tốn nhiều tiền hơn.

3 hữu ích 0 bình luận chia sẻ
2

Các phép đo phụ thuộc vào kích thước từ điển mặc dù. Đối với 10000 mục sao chép (d) và d.copy () gần như giống nhau.

a = {b: b for b in range(10000)} 
In [5]: %timeit copy(a)
10000 loops, best of 3: 186 µs per loop
In [6]: %timeit deepcopy(a)
100 loops, best of 3: 14.1 ms per loop
In [7]: %timeit a.copy()
1000 loops, best of 3: 180 µs per loop
2 hữu ích 0 bình luận chia sẻ
2

Tôi nhận ra đây là một chủ đề cũ, nhưng đây là kết quả cao trong các công cụ tìm kiếm cho "python sao chép chính tả" và kết quả hàng đầu cho "hiệu suất sao chép chính tả" và tôi tin rằng điều này có liên quan.

Từ Python 3.7, newDict = oldDict.copy()nhanh hơn tới 5,5 lần so với trước đây. Đáng chú ý, ngay bây giờ, newDict = dict(oldDict)dường như không có hiệu suất tăng này.

Có một chút thông tin ở đây .

2 hữu ích 0 bình luận chia sẻ
loading
Không tìm thấy câu trả lời bạn tìm kiếm? Duyệt qua các câu hỏi được gắn thẻ python performance dictionary copy , hoặc hỏi câu hỏi của bạn.

Có thể bạn quan tâm

loading