2016-12-09 22 views
13

Làm thế nào để chuyển đổi một danh sách bằng Python 3.5 như:Làm cách nào để chuyển đổi danh sách nhiều số nguyên thành một số nguyên?

x=[1, 3, 5] 

đến một int của 135 (cả int)?

+2

Tiêu đề chỉ nói "số nguyên" cho các yếu tố danh sách. Giá trị nào nên được trả lại cho, ví dụ: '[-3,14,0, -163]',? –

+0

Đầu ra: chữ không hợp lệ cho int() với số 10 –

+1

Nhưng mô tả của bạn không nói gì về danh sách đó là không hợp lệ, cũng không phải về chữ (danh sách các yếu tố không thể là biến?), Cũng không phải về cơ sở 10. (Và nó nói đầu ra một số nguyên duy nhất, không phải là "không hợp lệ".) –

Trả lời

26

Nếu bạn có một danh sách các int s và bạn muốn tham gia cùng họ với nhau, bạn có thể sử dụng map với str để chuyển đổi chúng thành các chuỗi, join chúng trên chuỗi rỗng và sau đó đúc trở lại int s với int.

Trong mã, điều này có vẻ như thế này:

r = int("".join(map(str, x))) 

r hiện nay có giá trị truy nã của 135.

Điều này, tất nhiên, là một cách tiếp cận hạn chế đi kèm với một số điều kiện. Nó yêu cầu danh sách được đề cập không chứa gì khác ngoài số dương int s (làm mẫu của bạn) hoặc chuỗi đại diện cho int s, nếu không thì các bước chuyển đổi thành chuỗi có thể không thành công hoặc việc tham gia (số âm) sẽ bị clunky.

+0

Đây là chậm hơn so với tính toán giá trị số, nhưng có lợi ích khi làm việc cho các cơ sở lớn hơn 10. – chepner

+0

@chepner nó sẽ nhanh hơn với số lượng lớn và phiên bản của bạn thường nhanh hơn với số lượng nhỏ hơn (30 chữ số và ít hơn trên máy tính của tôi). –

+0

Đáng chú ý rằng phiên bản này sẽ thất bại nếu số nguyên đầu tiên là 0. – asmeurer

30

Dưới đây là một cách toán học hơn mà không phải chuyển đổi qua lại thành chuỗi. Lưu ý rằng nó sẽ chỉ làm việc nếu 0 < = i < = 9.

>>> x = [1, 3, 5] 
>>> sum(d * 10**i for i, d in enumerate(x[::-1])) 
135 

Ý tưởng là để nhân mỗi phần tử trong danh sách bằng điện tương ứng của nó là 10 và sau đó để tổng hợp kết quả.

+2

Nếu bạn muốn nó có hiệu quả, tốt hơn là nên làm 'đảo ngược (x)' thay vì 'x [:: - 1]'? Sau này phải tạo ra một danh sách hoàn toàn mới, nhưng trước đây chỉ là một máy phát điện. – Justin

22

Chỉ sử dụng toán học (không chuyển đổi đến hoặc từ dây), bạn có thể sử dụng reduce function (functools.reduce bằng Python 3)

b = reduce(lambda total, d: 10*total + d, x, 0) 

Điều này làm cho sử dụng các quy tắc Horner, mà yếu tố đa thức đại diện cho số để giảm số lượng phép nhân. Ví dụ:

1357 = 1*10*10*10 + 3*10*10 + 5*10 + 7  # 6 multiplications 
    = ((1*10 + 3)*10 + 5)*10 + 7   # 3 multiplications 

Kết quả là, công suất này nhanh hơn 10 hoặc tạo chuỗi và chuyển kết quả thành số nguyên.

>>> timeit.timeit('reduce(lambda t,d: 10*t+d, x, 0)', 'from functools import reduce; x=[1,3,5,7]') 
0.7217515400843695 
>>> timeit.timeit('int("".join(map(str, [1,3,5,7])))') 
1.425914661027491 
>>> timeit.timeit('sum(d * 10**i for i, d in enumerate(x[::-1]))', 'x=[1,3,5,7]') 
1.897974518011324 

Công bằng mà nói, chuỗi chuyển đổi nhanh khi số chữ số được lớn hơn.

>>> import timeit 

# 30 digits 
>>> setup='from functools import reduce; x=[5, 2, 6, 8, 4, 6, 6, 4, 8, 0, 3, 1, 7, 6, 8, 2, 9, 9, 9, 5, 4, 5, 5, 4, 3, 6, 9, 2, 2, 1]' 
>>> print(timeit.timeit('reduce(lambda t,d: 10*t+d, x, 0)', setup)) 
6.520374411018565 
>>> print(timeit.timeit('int("".join(map(str, x)))', setup)) 
6.797425839002244 
>>> print(timeit.timeit('sum(d * 10**i for i, d in enumerate(x[::-1]))', setup)) 
19.430233853985555 

# 60 digits 
>>> setup='from functools import reduce; x=2*[5, 2, 6, 8, 4, 6, 6, 4, 8, 0, 3, 1, 7, 6, 8, 2, 9, 9, 9, 5, 4, 5, 5, 4, 3, 6, 9, 2, 2, 1]' 
>>> print(timeit.timeit('reduce(lambda t,d: 10*t+d, x, 0)', setup)) 
13.648188541992567 
>>> print(timeit.timeit('int("".join(map(str, x)))', setup)) 
12.864593736943789 
>>> print(timeit.timeit('sum(d * 10**i for i, d in enumerate(x[::-1]))', setup)) 
44.141602706047706 

# 120 digits! 
>>> setup='from functools import reduce; x=4*[5, 2, 6, 8, 4, 6, 6, 4, 8, 0, 3, 1, 7, 6, 8, 2, 9, 9, 9, 5, 4, 5, 5, 4, 3, 6, 9, 2, 2, 1]' 
>>> print(timeit.timeit('reduce(lambda t,d: 10*t+d, x, 0)', setup)) 
28.364255172084086 
>>> print(timeit.timeit('int("".join(map(str, x)))', setup)) 
25.184791765059344 
>>> print(timeit.timeit('sum(d * 10**i for i, d in enumerate(x[::-1]))', setup)) 
99.88558598596137 
+0

Điều đó sẽ không hoạt động với [1, 0, 'e', ​​3]! –

+1

@ LoïcFaure-Lacroix OP đặc biệt hỏi về một mảng các số nguyên – brianpck

+0

@brianpck có, tôi biết nhưng chung chung đôi khi tốt hơn không. Btw, các bài kiểm tra timeit là một cách tốt để kiểm tra mọi thứ. Câu trả lời không nói rằng phương pháp giảm sẽ tồi tệ hơn với số lượng lớn. Đó là tốt với số lượng nhỏ hơn nhưng ngay sau khi nó sẽ nhận được con số với chiều dài khoảng 30 con số, phiên bản str sẽ là giải pháp nhanh nhất. –

1

Nếu bạn không thích bản đồ mà bạn luôn có thể sử dụng danh sách hiểu:

s = [str(i) for i in x] 
r = int("".join(s)) 
+0

... và nếu bạn thích việc hiểu danh sách, bạn luôn có thể sử dụng biểu thức trình tạo và tránh một trong các vòng lặp: 'int (" ". Nối (str (i) cho i trong x))' – Kroltan

Các vấn đề liên quan