Giải pháp này có thể hơi quá mức đối với áp phích gốc, nhưng tôi nghĩ tôi sẽ chia sẻ mã mà tôi đã sử dụng để giải quyết vấn đề này và các vấn đề tương tự.
Đó là một chút dài (khoảng 90 dòng), nhưng nếu bạn thường có nhu cầu này, muốn sử dụng trực tuyến dễ sử dụng và cần môi trường miễn phí tinh khiết Python, thì tôi cho rằng nó có thể được sử dụng.
Về cơ bản, điều duy nhất bạn phải làm là vượt qua danh sách của bạn với chức năng và nói với nó dài những gì bạn muốn danh sách mới của bạn được, và các chức năng sẽ hoặc là:
- giảm bớt danh sách của bạn bằng cách thả các mục nếu độ dài mới nhỏ hơn, giống như các câu trả lời trước đã được đề xuất.
- căng/cao cấp danh sách của bạn (trái ngược với tinh giản biên chế) nếu chiều dài mới là lớn hơn, với các tùy chọn bổ sung mà bạn có thể quyết định:
- tuyến tính suy bw các giá trị được biết đến (tự động chọn nếu danh sách chứa ints hoặc phao)
- lặp lại mỗi giá trị để họ chiếm một kích thước tương ứng của danh sách mới (tự động chọn nếu danh sách chứa không số)
- kéo giá trị ban đầu ngoài và để lại những khoảng trống ở giữa
Mọi thứ được thu thập bên trong một chức năng vì vậy nếu bạn cần nó chỉ cần sao chép và dán nó vào tập lệnh của bạn và bạn có thể bắt đầu sử dụng nó ngay lập tức.
Ví dụ bạn có thể nói:
origlist = [0,None,None,30,None,50,60,70,None,None,100]
resizedlist = ResizeList(testlist, 21)
print(resizedlist)
và nhận
[0, 5.00000000001, 9.9999999999900009, 15.0, 20.000000000010001, 24.999999999989999, 30, 35.0, 40.0, 45.0, 50.0, 55.0, 60.0, 65.0, 70, 75.000000000010004, 79.999999999989996, 85.0, 90.000000000010004, 94.999999999989996, 100]
Lưu ý rằng không chính xác nhỏ sẽ xảy ra do hạn chế về dấu chấm động. Ngoài ra, tôi đã viết này cho Python 2.x, do đó, để sử dụng nó trên Python 3.x chỉ cần thêm một dòng duy nhất cho biết xrange = range
.
Và đây là một thủ thuật tiện lợi để nội suy giữa các phần con được định vị trong danh sách các danh sách. Vì vậy, ví dụ bạn có thể dễ dàng nội suy giữa các bộ màu RGB để tạo ra một gradient màu sắc của x nr các bước. Giả sử một danh sách các hàng màu RGB của 3 và một biến GRADIENTLENGTH mong muốn bạn làm điều này với:
crosssections = zip(*rgbtuples)
grad_crosssections = (ResizeList(spectrum,GRADIENTLENGTH) for spectrum in crosssections)
rgb_gradient = [list(each) for each in zip(*grad_crosssections)]
Nó có thể có thể cần một vài tối ưu hóa, tôi đã phải làm khá nhiều thử nghiệm. Nếu bạn cảm thấy bạn có thể cải thiện, hãy chỉnh sửa bài đăng của tôi. Đây là mã:
def ResizeList(rows, newlength, stretchmethod="not specified", gapvalue=None):
"""
Resizes (up or down) and returns a new list of a given size, based on an input list.
- rows: the input list, which can contain any type of value or item (except if using the interpolate stretchmethod which requires floats or ints only)
- newlength: the new length of the output list (if this is the same as the input list then the original list will be returned immediately)
- stretchmethod: if the list is being stretched, this decides how to do it. Valid values are:
- 'interpolate'
- linearly interpolate between the known values (automatically chosen if list contains ints or floats)
- 'duplicate'
- duplicate each value so they occupy a proportional size of the new list (automatically chosen if the list contains non-numbers)
- 'spread'
- drags the original values apart and leaves gaps as defined by the gapvalue option
- gapvalue: a value that will be used as gaps to fill in between the original values when using the 'spread' stretchmethod
"""
#return input as is if no difference in length
if newlength == len(rows):
return rows
#set auto stretchmode
if stretchmethod == "not specified":
if isinstance(rows[0], (int,float)):
stretchmethod = "interpolate"
else:
stretchmethod = "duplicate"
#reduce newlength
newlength -= 1
#assign first value
outlist = [rows[0]]
writinggapsflag = False
if rows[1] == gapvalue:
writinggapsflag = True
relspreadindexgen = (index/float(len(rows)-1) for index in xrange(1,len(rows))) #warning a little hacky by skipping first index cus is assigned auto
relspreadindex = next(relspreadindexgen)
spreadflag = False
gapcount = 0
for outlistindex in xrange(1, newlength):
#relative positions
rel = outlistindex/float(newlength)
relindex = (len(rows)-1) * rel
basenr,decimals = str(relindex).split(".")
relbwindex = float("0."+decimals)
#determine equivalent value
if stretchmethod=="interpolate":
#test for gap
maybecurrelval = rows[int(relindex)]
maybenextrelval = rows[int(relindex)+1]
if maybecurrelval == gapvalue:
#found gapvalue, so skipping and waiting for valid value to interpolate and add to outlist
gapcount += 1
continue
#test whether to interpolate for previous gaps
if gapcount > 0:
#found a valid value after skipping gapvalues so this is where it interpolates all of them from last valid value to this one
startvalue = outlist[-1]
endindex = int(relindex)
endvalue = rows[endindex]
gapstointerpolate = gapcount
allinterpolatedgaps = Resize([startvalue,endvalue],gapstointerpolate+3)
outlist.extend(allinterpolatedgaps[1:-1])
gapcount = 0
writinggapsflag = False
#interpolate value
currelval = rows[int(relindex)]
lookahead = 1
nextrelval = rows[int(relindex)+lookahead]
if nextrelval == gapvalue:
if writinggapsflag:
continue
relbwval = currelval
writinggapsflag = True
else:
relbwval = currelval + (nextrelval - currelval) * relbwindex #basenr pluss interindex percent interpolation of diff to next item
elif stretchmethod=="duplicate":
relbwval = rows[int(round(relindex))] #no interpolation possible, so just copy each time
elif stretchmethod=="spread":
if rel >= relspreadindex:
spreadindex = int(len(rows)*relspreadindex)
relbwval = rows[spreadindex] #spread values further apart so as to leave gaps in between
relspreadindex = next(relspreadindexgen)
else:
relbwval = gapvalue
#assign each value
outlist.append(relbwval)
#assign last value
if gapcount > 0:
#this last value also has to interpolate for previous gaps
startvalue = outlist[-1]
endvalue = rows[-1]
gapstointerpolate = gapcount
allinterpolatedgaps = Resize([startvalue,endvalue],gapstointerpolate+3)
outlist.extend(allinterpolatedgaps[1:-1])
outlist.append(rows[-1])
gapcount = 0
writinggapsflag = False
else:
outlist.append(rows[-1])
return outlist
Bạn có thể xây dựng một chút không? Cảm ơn. – Dave
Bắt đầu với bộ đếm ở 0. Trong khi bộ đếm nhỏ hơn độ dài của danh sách: cho ra phần tử của danh sách có chỉ mục là giá trị của bộ đếm, được làm sàn, rồi tăng bộ đếm. –