দশমিক পরিসর () পদক্ষেপের মানটি কীভাবে ব্যবহার করবেন?


742

0 এবং 1 দ্বারা 0.1 দ্বারা পা রাখার কোনও উপায় আছে?

আমি ভেবেছিলাম আমি নীচের মতো এটি করতে পারি তবে এটি ব্যর্থ হয়েছিল:

for i in range(0, 1, 0.1):
    print i

পরিবর্তে, এটি বলে যে পদক্ষেপ যুক্তি শূন্য হতে পারে না, যা আমি আশা করি না।


17
int (0.1) == 0, সুতরাং পদক্ষেপটি আসলে শূন্য। এটি অপ্রত্যাশিত হতে পারে তবে এটি শূন্য। আপনি নিজের প্রশ্নটি পুনরায় পুনঃস্থাপন করতে চাইলে এই সত্যটি প্রতিফলিত হতে পারে যে এটি আপনি প্রত্যাশা করেননি। "এটি নয়" বলা মিথ্যা এবং বিভ্রান্তিকর।
এস .লট

3
BTW একটি সংক্ষিপ্ত এক-লাইনের ব্যবহার গুটান করা যাবে itertools.takewhileএবং itertools.countdrangeযদিও এটি পারফরম্যান্স-বুদ্ধিমানের চেয়ে ভাল নয় ।
Kos

1
এটি বিব্রতকর যে অজগরটির পরিসীমা এটির অনুমতি দেয় না, প্রদত্ত গোলাকার ত্রুটিগুলি সংগ্রহ না করেও এমন একটি জেনারেটর বাস্তবায়ন করা কতটা সহজ given মুরগি, এমনকি seqজিএনইউ কোর্টিলগুলিতে থাকা সরঞ্জামটি গোলাকৃতির seq 0 0.1 1ত্রুটিগুলি ছাড়াই কোনওটিকে মঞ্জুরি দেয় !
জোছ

3
@josch: seqসি ব্যবহার long doubleটাইপ অভ্যন্তরীণভাবে এবং হয় rounding ত্রুটির বিষয়। আমার মেশিনে উদাহরণস্বরূপ, seq 0 0.1 1দেয় 1(প্রত্যাশিত হিসাবে) তার শেষ আউটপুট কিন্তু seq 1 0.1 2দেয় 1.9গত আউটপুট (বদলে প্রত্যাশিত 2)।
মার্ক ডিকিনসন

সুবিধার্থে, @ কোসের পরামর্শটি বাস্তবায়িত হতে পারে itertools.takewhile(lambda x: (x+0.05)<1, itertools.count(0,0.1))বা itertools.islice(itertools.count(0,0.1), 10)(আপনার পরে import itertools), যদিও আমি পরীক্ষিত করি নি যা কোনটি বেশি কার্যকর
বেনামে

উত্তর:


905

সরাসরি দশমিক পদক্ষেপ ব্যবহার না করে আপনি কয়টি পয়েন্ট চান তার পরিপ্রেক্ষিতে এটি প্রকাশ করা আরও নিরাপদ। অন্যথায়, ভাসমান-পয়েন্ট রাউন্ডিং ত্রুটি সম্ভবত আপনাকে একটি ভুল ফলাফল দেয়।

আপনি ব্যবহার করতে পারেন linspace থেকে ফাংশন NumPy লাইব্রেরী (যেটি মান লাইব্রেরির অংশ নয় কিন্তু প্রাপ্ত অপেক্ষাকৃত সহজ হয়)। linspaceফিরে আসতে বেশ কয়েকটি পয়েন্ট নেয় এবং ডানদিকের শেষ পয়েন্টটি অন্তর্ভুক্ত করার জন্য আপনাকে নির্দিষ্ট করতে দেয়:

>>> np.linspace(0,1,11)
array([ 0. ,  0.1,  0.2,  0.3,  0.4,  0.5,  0.6,  0.7,  0.8,  0.9,  1. ])
>>> np.linspace(0,1,10,endpoint=False)
array([ 0. ,  0.1,  0.2,  0.3,  0.4,  0.5,  0.6,  0.7,  0.8,  0.9])

আপনি যদি সত্যিই কোনও ভাসমান-পয়েন্ট ধাপের মানটি ব্যবহার করতে চান তবে আপনি এটি সহ করতে পারেন numpy.arange

>>> import numpy as np
>>> np.arange(0.0, 1.0, 0.1)
array([ 0. ,  0.1,  0.2,  0.3,  0.4,  0.5,  0.6,  0.7,  0.8,  0.9])

যদিও ভাসমান-পয়েন্ট রাউন্ডিং ত্রুটি সমস্যা তৈরি করবে । এখানে একটি সহজ কেস রয়েছে যেখানে রাউন্ডিং ত্রুটি arangeদৈর্ঘ্য -4 অ্যারে তৈরি করে যখন এটি কেবল 3 টি সংখ্যা তৈরি করে:

>>> numpy.arange(1, 1.3, 0.1)
array([1. , 1.1, 1.2, 1.3])

51
অদ্ভুত একটি পাইথনের এমন সর্বব্যাপী উপাদান যা এই উত্তরটিকে আমি সবচেয়ে 'পাইথোনিক' হিসাবে বিবেচনা করি।
এয়ারট্রাইক

21
@ অ্যান্ড্রেটার সমস্যাটি হ'ল @ নম্পি @ একটি তৃতীয় পক্ষের প্যাকেজ এবং নির্ভরতা-পরিচালনা, সঞ্চয়স্থান (প্যাকেজের জন্য নিজেই) ইত্যাদির ক্ষেত্রে প্রচুর ওভারহেড যুক্ত করে adds ইত্যাদি বিকাশকারী কী করছে তার উপর নির্ভর করে এটি ব্যবহার করা অসম্ভব এটা।
rbaleksandar

আমাকে ক্ষমা করুন, তবে আমি শেষ অংশে ভাসমান পয়েন্টটি গোল করার ত্রুটিটি বুঝতে পারি নি np.linspace(1.,1.3,4)এবং np.arange(1.,1.3,0.1)ঠিক একই আউটপুটটি
দিয়েছি

4
@ ডেডকোড কারণ হ'ল এনপি.আরানজ একটি পরিসীমা উত্পাদন করার জন্য সংজ্ঞায়িত করা হয়েছে [start,stop)(অর্থাত্ বাদ দিয়ে stop) সুতরাং কেউ 1.3 তালিকায় অন্তর্ভুক্ত হওয়ার আশা করবেন না। কেন এটি এখনও অন্তর্ভুক্ত রয়েছে এবং এর বিপরীতে কী করা উচিত এই প্রশ্নটি দেখুন ।
ডেনিস

5
কোন প্যাকেজটি কীভাবে ব্যবহৃত হবে তা "পাইথোনিক" কিনা তা কোনও সূচক নয়।
অ্যালেক্স হল

213

পাইথনের ব্যাপ্তি () কেবলমাত্র পূর্ণসংখ্যা করতে পারে, ভাসমান বিন্দুতে নয়। আপনার নির্দিষ্ট ক্ষেত্রে, আপনি পরিবর্তে একটি তালিকা বোঝার ব্যবহার করতে পারেন:

[x * 0.1 for x in range(0, 10)]

(কলটি প্রতিবেদনের সাথে পরিসীমাতে প্রতিস্থাপন করুন))

আরও সাধারণ ক্ষেত্রে, আপনি একটি কাস্টম ফাংশন বা জেনারেটর লিখতে চাইতে পারেন।


36
আরও ভাল, আপনি পাইথন ২.৪+ এর সাথে কাজ করে থাকলে আপনি কেবল একটি জেনারেটর বোঝাপড়া ব্যবহার করতে পারেন। (x * 0.1 for x in range(0, 10))
জ্যাব

42
এর চেয়েও ভাল, এর x/10পরিবর্তে রাখুন x * 0.1: ডি আসলে বিশেষ কিছু নয়, তবে কিছু কিছু সংখ্যক আরও সুনির্দিষ্ট হবে, যেমন 3*0.1আপনি পাবেন 0.30000000000000004, 3-10 এর জন্য আপনি পেয়ে যাবেন 0.3:)
ব্ল্যাক

4
3/10 আমাকে 0 দেয়, 0.3 নয়। 3 / 10.0 0.29999999999999999 দেয়। পাইথন 2.6।

19
@ লার্স ভাইর্জনিয়াস: পাইথন ২.২++ এ, ০.০ প্রদান করে from __future__ import division; 3/10। পাইথন ৩.x এ এই ব্যবহারটি ডিফল্ট is
বেঞ্জামিন হজসন

2
বৃত্তাকার ফাংশন ব্যবহার lst = [বৃত্তাকার (এক্স * 0.10,2) পরিসীমা (0,10) এ x এর জন্য] হতে পারে
মার্ক

148

উপর নির্মাণের 'xrange ([শুরু], স্টপ [, ধাপ])' , আপনি একটি জেনারেটরের গ্রহণ এবং (সমর্থনকারী প্রকারের লাঠি কোনো ধরনের আপনার চয়ন করা উৎপন্ন বর্ণনা করতে পারেন +এবং <):

>>> def drange(start, stop, step):
...     r = start
...     while r < stop:
...         yield r
...         r += step
...         
>>> i0=drange(0.0, 1.0, 0.1)
>>> ["%g" % x for x in i0]
['0', '0.1', '0.2', '0.3', '0.4', '0.5', '0.6', '0.7', '0.8', '0.9', '1']
>>> 

45
এতে রাউন্ডঅফ সমস্যা রয়েছে। দয়া করে এখানে দেখুন: কোড. activestate.com/recines/66472
খ্রিস্টান ওডার্ড

আমি একে অন্য দিকের জন্য কিছুটা প্রসারিত করব (যখন r> স্টপ) এবং বিপরীত দিকটি দেওয়ার জন্য একটি সম্পর্কিত r - = পদক্ষেপ।
user318904

1
উপরে উল্লিখিত ভাসমান নির্ভুলতা সমস্যা ছাড়াই আমি একটি এক্সফ্রেঞ্জ ফাংশন করেছি। এটি দেখুন;) স্ট্যাকওভারফ্লো
কার্লোস ভেগা

1
আপনি রাউন্ডিং ত্রুটিগুলি জমা করছেন। পরিবর্তে এটি ব্যবহার করুন: `i = 0; আর = স্টপ করার সময় আর = শুরু করুন: i + = 1; r = start + i * পদক্ষেপ; ফলন r`
সিস টিমারম্যান

1
এটি পাইথোনসেন্ট্রাল.আইও / পাইথনস-অ্যারেঞ্জ- ফাংশন- এক্সপ্লাইন্ড (এবং অন্যান্য পাইথন ডকুমেন্টেশন উত্স) থেকে
অ্যাপোস্টোলোস

31

লুপটির পরিমাণ বাড়িয়ে নিন iএবং তারপরে আপনার যখন প্রয়োজন হবে তখন এটি হ্রাস করুন।

for i * 100 in range(0, 100, 10):
    print i / 100.0

সম্পাদনা: কেন আমি ভেবেছিলাম যে সিন্টেক্সটিকভাবে কাজ করবে তা আমি সত্যই মনে করতে পারি না

for i in range(0, 11, 1):
    print i / 10.0

এর কাঙ্ক্ষিত আউটপুট থাকা উচিত।


আমি মনে করি আপনি এই পরিসীমাটি () পূর্ণসংখ্যার কাজ করে যাবেন, একই ক্ষেত্রে কমপক্ষে একই ফাংশনটি ব্যবহার করে এটিই একমাত্র সমাধান হবে।
ম্যাথু শার্লে

1
@ কেএমএসজিআর সৃজনশীল: ডি মাত্র একটি ছোট জিনিস: পাইথন ২.x ব্যবহার করলে পাইথনকে ফলাফল কেটে ফেলার জন্য ১০০.০ দিয়ে ভাগ করুন by আমি মনে করি 3.0.০ এ, আপনি কোড করে যাবেন তাই এটি কাজ করবে।
দানা

2
for i * 100 in range(0, 100, 10): সিনট্যাক্স এরর: অপারেটরকে বরাদ্দ করতে পারে না
আন ভ্যান রসম

25

scipyএকটি বিল্ট ইন ফাংশন রয়েছে arangeযা পাইথনের range()কনস্ট্রাক্টরকে আপনার ফ্লোট হ্যান্ডলিংয়ের প্রয়োজনীয়তা মেটাতে সাধারণীকরণ করে ।

from scipy import arange


8
এটি প্রকৃতপক্ষে ঠিক যা arangeআপনি নাম্বারে খুঁজে পেতে পারেন: >>> import scipy >>> import numpy >>> numpy.arange is scipy.arangeফিরে আসবে True
iFreilicht

from nump import arange as range
শ্রুউমাউস

24

নুমপি কিছুটা ওভারকিল, আমার মনে হয়।

[p/10 for p in range(0, 10)]
[0.0, 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9]

সাধারণভাবে বলতে গেলে, আপনার কাছে ধাপে ধাপে 1/xকরা ywould

x=100
y=2
[p/x for p in range(0, int(x*y))]
[0.0, 0.01, 0.02, 0.03, ..., 1.97, 1.98, 1.99]

( 1/xআমি পরীক্ষার সময় কম গোলাকার শব্দ উত্পন্ন)।


18

আর এর seq ফাংশনের অনুরূপ , এটি সঠিক পদক্ষেপের মান প্রদানে যে কোনও ক্রমে একটি ক্রম দেয়। শেষ মানটি স্টপ মানের সমান।

def seq(start, stop, step=1):
    n = int(round((stop - start)/float(step)))
    if n > 1:
        return([start + step*i for i in range(n+1)])
    elif n == 1:
        return([start])
    else:
        return([])

ফলাফল

seq(1, 5, 0.5)

[1.0, 1.5, 2.0, 2.5, 3.0, 3.5, 4.0, 4.5, 5.0]

seq(10, 0, -1)

[10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0]

seq(10, 0, -2)

[10, 8, 6, 4, 2, 0]

seq(1, 1)

[1]


2
এটি এমন এক ব্যক্তির পক্ষে দুর্দান্ত উত্তর যা পাইথনটিতে খুব বেশি না গিয়েই এটি পেতে চায়।
চানি

1
যে ছিল প্রায় কি আমি খুঁজছেন ছিল - দয়া করে মনে রাখবেন seq(0.5, 3.0)আয় [0.5, 1.5, 2.5, 3.5]। গত এন্ট্রি আউট-অফ-পরিসীমা হওয়া এড়াতে, প্রতিস্থাপন n = int(round(...সঙ্গে n = int(floor(...লাইন দিয়ে from math import floorশীর্ষ (উপরে এ def seq(...)।
ফ্রেন্ডএফএক্স

2
@ ফ্রেন্ডএফএক্স এটি করবেন না! যদি floorএটি ব্যবহার করা হয় তবে seq(0.2, 0.9, 0.1)ডান প্রান্তে পৌঁছাতে ব্যর্থ হবে এবং ফিরে আসবে[0.2, 0.30000000000000004, 0.4, 0.5, 0.6000000000000001, 0.7, 0.8]
fdermishin

@ ইউজার 502144: চমৎকার ধরা, ধন্যবাদ আমার ধারণা এটি সাধারণ রাখার জন্য আমাকে আরও জটিল সমাধানগুলির একটি সমাধান করতে হবে।
ফ্রেন্ডএফএক্স

14

অন্তর্নির্মিত ফাংশনটি পূর্ণসংখ্যার মানগুলির একটি ক্রম দেয়, আমি ভীত, তাই আপনি এটি একটি দশমিক পদক্ষেপটি ব্যবহার করতে পারবেন না।

আমি বলবো কিছুক্ষণ লুপ ব্যবহার করুন:

i = 0.0
while i <= 1.0:
    print i
    i += 0.1

আপনি যদি কৌতূহলী হন তবে পাইথন আপনার 0.1 থেকে 0 তে রূপান্তর করছে, এ কারণেই এটি আপনাকে বলছে তর্কটি শূন্য হতে পারে না।


2
এটা করবেন না! যোগ করার পদ্ধতি .110 বার যোগ হিসাবে একই নয় 1! docs.oracle.com/cd/E19957-01/806-3568/ncg_goldberg.html
বিড়াল

12

ইটারটুলগুলি ব্যবহার করে একটি সমাধান এখানে দেওয়া হয়েছে :

import itertools

def seq(start, end, step):
    if step == 0:
        raise ValueError("step must not be 0")
    sample_count = int(abs(end - start) / step)
    return itertools.islice(itertools.count(start, step), sample_count)

ব্যবহারের উদাহরণ:

for i in seq(0, 1, 0.1):
    print(i)

সম্পূর্ণতার স্বার্থে, আপনি নমুনা_কাউন্ট ভেরিয়েবলের জন্য নিখুঁত মান গণনা করতে হবে, এইভাবে আপনার ফাংশনটি নেতিবাচক সূচনার জন্যও কাজ করবে (উদাহরণস্বরূপ -10 থেকে 10 পর্যন্ত)
ডিলিটম্যান

10
[x * 0.1 for x in range(0, 10)] 

পাইথন ২.7 এক্স আপনাকে ফলাফল দেয়:

[0.0, 0.1, 0.2, 0.30000000000000004, 0.4, 0.5, 0.60000000000000011, 0.70000000000000011, 0.8, 0.9]

তবে আপনি যদি ব্যবহার করেন:

[ round(x * 0.1, 1) for x in range(0, 10)]

আপনাকে পছন্দসই দেয়:

[0.0, 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9]


9
import numpy as np
for i in np.arange(0, 1, 0.1): 
    print i 

এটির গোলটি ইস্যু রয়েছে, উদ্ধৃতি: "0.1 এর মতো একটি অ-পূর্ণসংখ্যার পদক্ষেপ ব্যবহার করার পরে ফলাফলগুলি বেশিরভাগ ক্ষেত্রে সামঞ্জস্যপূর্ণ হয় না।" - docs.scipy.org/doc/numpy/references/generated/numpy.arange.html
গ্যালাকটিকা

5

এবং আপনি যদি এটি প্রায়শই করেন তবে আপনি উত্পন্ন তালিকাটি সংরক্ষণ করতে পারেন r

r=map(lambda x: x/10.0,range(0,10))
for i in r:
    print i

5

more_itertoolsএকটি তৃতীয় পক্ষের গ্রন্থাগার যা একটি numeric_rangeসরঞ্জাম প্রয়োগ করে :

import more_itertools as mit


for x in mit.numeric_range(0, 1, 0.1):
    print("{:.1f}".format(x))

আউটপুট

0.0
0.1
0.2
0.3
0.4
0.5
0.6
0.7
0.8
0.9

এই টুলের জন্য কাজ করে Decimalএবং Fraction


4

আমার সংস্করণগুলি শিফটের জন্য গুণিত সূচকগুলি তৈরি করতে আসল পরিসীমা ফাংশনটি ব্যবহার করে। এটি মূল বিন্যাসের ক্রিয়ায় একই সিনট্যাক্সের অনুমতি দেয়। আমি দুটি সংস্করণ তৈরি করেছি, একটি ভাসা এবং একটি ডেসিমাল ব্যবহার করে, কারণ আমি দেখেছি যে কিছু ক্ষেত্রে আমি ভাসমান পয়েন্ট গণিত দ্বারা প্রবর্তিত রাউন্ডঅফ ড্রিফটটি এড়াতে চেয়েছিলাম।

এটি পরিসীমা / এক্সরেঞ্জের মতো খালি সেট ফলাফলের সাথে সামঞ্জস্যপূর্ণ।

উভয় ফাংশনে কেবলমাত্র একটি একক সংখ্যাসূচক মান পাস করলে স্ট্যান্ডার্ড রেঞ্জের আউটপুট ইনপুট প্যারামিটারের পূর্ণ সিলিং মানকে ফিরে আসবে (সুতরাং আপনি যদি এটি 5.5 দিয়ে থাকেন তবে এটি পরিসীমা (6) প্রদান করবে)

সম্পাদনা: নিচের কোড এখন pypi উপর প্যাকেজ হিসাবে উপলব্ধ: Franges

## frange.py
from math import ceil
# find best range function available to version (2.7.x / 3.x.x)
try:
    _xrange = xrange
except NameError:
    _xrange = range

def frange(start, stop = None, step = 1):
    """frange generates a set of floating point values over the 
    range [start, stop) with step size step

    frange([start,] stop [, step ])"""

    if stop is None:
        for x in _xrange(int(ceil(start))):
            yield x
    else:
        # create a generator expression for the index values
        indices = (i for i in _xrange(0, int((stop-start)/step)))  
        # yield results
        for i in indices:
            yield start + step*i

## drange.py
import decimal
from math import ceil
# find best range function available to version (2.7.x / 3.x.x)
try:
    _xrange = xrange
except NameError:
    _xrange = range

def drange(start, stop = None, step = 1, precision = None):
    """drange generates a set of Decimal values over the
    range [start, stop) with step size step

    drange([start,] stop, [step [,precision]])"""

    if stop is None:
        for x in _xrange(int(ceil(start))):
            yield x
    else:
        # find precision
        if precision is not None:
            decimal.getcontext().prec = precision
        # convert values to decimals
        start = decimal.Decimal(start)
        stop = decimal.Decimal(stop)
        step = decimal.Decimal(step)
        # create a generator expression for the index values
        indices = (
            i for i in _xrange(
                0, 
                ((stop-start)/step).to_integral_value()
            )
        )  
        # yield results
        for i in indices:
            yield float(start + step*i)

## testranges.py
import frange
import drange
list(frange.frange(0, 2, 0.5)) # [0.0, 0.5, 1.0, 1.5]
list(drange.drange(0, 2, 0.5, precision = 6)) # [0.0, 0.5, 1.0, 1.5]
list(frange.frange(3)) # [0, 1, 2]
list(frange.frange(3.5)) # [0, 1, 2, 3]
list(frange.frange(0,10, -1)) # []

frangeস্টপ হলে কীভাবে কাজ করা যায় None? কোডটির সেই অংশটি আর পদক্ষেপের আকার বিবেচনা করে না।
জোশ

1
@ জোশের rangeদু'টি স্বাক্ষর রয়েছে: এটি range(stop)একটি ডিফল্ট ধরে নেয় start=0, step=1এবং range(start, stop, step)যেখানে অনুমান করা হয় না। frangeযে প্রতিফলিত। যখন ব্যবহার range(stop)স্বাক্ষর, উভয় frangeএবং drange1 0 এবং বৃদ্ধি এ শুরু, তাই তাদের আচরণ নিয়মিত অভিন্ন range(stop)নিকটতম পূর্ণসংখ্যায় প্রকাশ করে স্টপ সঙ্গে আচরণ।
নিসান.এইচ

4

ভাসা পদক্ষেপের সাথে রেঞ্জগুলি পেতে এটি আমার সমাধান।
এই ফাংশনটি ব্যবহার করে নম্পতি আমদানি করা বা এটি ইনস্টল করা প্রয়োজন হয় না।
আমি নিশ্চিত যে এটি উন্নত এবং অনুকূলিত হতে পারে। নির্দ্বিধায় এটি করতে এবং এটি এখানে পোস্ট করুন।

from __future__ import division
from math import log

def xfrange(start, stop, step):

    old_start = start #backup this value

    digits = int(round(log(10000, 10)))+1 #get number of digits
    magnitude = 10**digits
    stop = int(magnitude * stop) #convert from 
    step = int(magnitude * step) #0.1 to 10 (e.g.)

    if start == 0:
        start = 10**(digits-1)
    else:
        start = 10**(digits)*start

    data = []   #create array

    #calc number of iterations
    end_loop = int((stop-start)//step)
    if old_start == 0:
        end_loop += 1

    acc = start

    for i in xrange(0, end_loop):
        data.append(acc/magnitude)
        acc += step

    return data

print xfrange(1, 2.1, 0.1)
print xfrange(0, 1.1, 0.1)
print xfrange(-1, 0.1, 0.1)

আউটপুটটি হ'ল:

[1.0, 1.1, 1.2, 1.3, 1.4, 1.5, 1.6, 1.7, 1.8, 1.9, 2.0]
[0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1.0, 1.1]
[-1.0, -0.9, -0.8, -0.7, -0.6, -0.5, -0.4, -0.3, -0.2, -0.1, 0.0]

1
শেষ মানটি যদি স্টপ মানের 1 টি ধাপের মধ্যে থাকে তবে এটি হারিয়ে যাওয়ার ক্ষেত্রে একটি ত্রুটি রয়েছে। অর্থাত্ xfrange (1,10,2) কেবল 1,3,5,7 করে, 9 নিখোঁজ
লোব

রেফারেন্স এবং অন্যান্য পাঠকদের জন্য, দয়া করে এই বাস্তবায়নটিকে এই স্ট্যাকওভারফ্লো . com/a/477610/54964 এর সাথে তুলনা করুন । এটিতে বড় ফ্লোটের সমস্যা বলে মনে হয় না।
লিও লোপোল্ড হার্টজ 준영

@ কার্লোসভেগা আপনি কি নিশ্চিত করতে পারেন যে লব কেন তার ফলাফল পেয়েছে?
লিও লোপোল্ড হার্টজ 준영

3

বুটিকের সম্পূর্ণতার জন্য, একটি কার্যকরী সমাধান:

def frange(a,b,s):
  return [] if s > 0 and a > b or s < 0 and a < b or s==0 else [a]+frange(a+s,b,s)

2

আপনি এই ফাংশনটি ব্যবহার করতে পারেন:

def frange(start,end,step):
    return map(lambda x: x*step, range(int(start*1./step),int(end*1./step)))

সঠিকভাবে কাজ করছে বলে মনে হচ্ছে নাlist(frange(99.8, 100.1, 0.1)) => [99.7, 99.80000000000001, 99.9]
শাই কলম্যান

2

কৌতুক এড়াতে বৃত্তাকার বন্ধ সমস্যা , পরিসর মাধ্যমে সরানো করার জন্য একটি পৃথক নম্বর ব্যবহার হল শুরু হয় এবং অর্ধেক পদক্ষেপ এগিয়ে শুরু

# floating point range
def frange(a, b, stp=1.0):
  i = a+stp/2.0
  while i<b:
    yield a
    a += stp
    i += stp

বিকল্পভাবে, numpy.arangeব্যবহার করা যেতে পারে।


2

এটি নম্পি লাইব্রেরি ব্যবহার করে করা যেতে পারে। আরেঞ্জ () ফাংশনটি ভাসমান পদক্ষেপের অনুমতি দেয়। তবে, এটি একটি অদ্ভুত অ্যারে প্রদান করে যা আমাদের সুবিধার জন্য টোলিস্ট () ব্যবহার করে তালিকায় রূপান্তর করতে পারে।

for i in np.arange(0, 1, 0.1).tolist():
   print i

2

আমার উত্তরটি মানচিত্র () ব্যবহার করে, NumPy এর প্রয়োজন ছাড়াই এবং ল্যাম্বদা ব্যবহার না করে (যদিও আপনি পারতেন) অন্যের মতো similar তারিখের পদক্ষেপে 0.0 থেকে t_max পর্যন্ত ভাসমান মানগুলির তালিকা পেতে:

def xdt(n):
    return dt*float(n)
tlist  = map(xdt, range(int(t_max/dt)+1))

2

সুপারভাইজড কেউই পাইথন 3 ডক্সে প্রস্তাবিত সমাধানটি এখনও উল্লেখ করেনি :

আরো দেখুন:

  • Linspace রেসিপি দেখায় কিভাবে যে ফ্লোটিং পয়েন্ট অ্যাপ্লিকেশনের জন্য উপযুক্ত পরিসীমা একটি অলস সংস্করণ বাস্তবায়ন।

একবার সংজ্ঞায়িত হয়ে গেলে, রেসিপিটি ব্যবহার করা সহজ এবং প্রয়োজন হয় না numpyবা অন্য কোনও বাহ্যিক গ্রন্থাগার নয়, তবে ফাংশনগুলি পছন্দ করে numpy.linspace()। দ্রষ্টব্য যে stepযুক্তির পরিবর্তে তৃতীয় numযুক্তি পছন্দসই মানগুলির সংখ্যা নির্দিষ্ট করে:

print(linspace(0, 10, 5))
# linspace(0, 10, 5)
print(list(linspace(0, 10, 5)))
# [0.0, 2.5, 5.0, 7.5, 10]

আমি নীচে অ্যান্ড্রু বার্নার্টের পূর্ণ পাইথন 3 রেসিপিটির একটি পরিবর্তিত সংস্করণ উদ্ধৃত করেছি:

import collections.abc
import numbers

class linspace(collections.abc.Sequence):
    """linspace(start, stop, num) -> linspace object

    Return a virtual sequence of num numbers from start to stop (inclusive).

    If you need a half-open range, use linspace(start, stop, num+1)[:-1].
    """
    def __init__(self, start, stop, num):
        if not isinstance(num, numbers.Integral) or num <= 1:
            raise ValueError('num must be an integer > 1')
        self.start, self.stop, self.num = start, stop, num
        self.step = (stop-start)/(num-1)
    def __len__(self):
        return self.num
    def __getitem__(self, i):
        if isinstance(i, slice):
            return [self[x] for x in range(*i.indices(len(self)))]
        if i < 0:
            i = self.num + i
        if i >= self.num:
            raise IndexError('linspace object index out of range')
        if i == self.num-1:
            return self.stop
        return self.start + i*self.step
    def __repr__(self):
        return '{}({}, {}, {})'.format(type(self).__name__,
                                       self.start, self.stop, self.num)
    def __eq__(self, other):
        if not isinstance(other, linspace):
            return False
        return ((self.start, self.stop, self.num) ==
                (other.start, other.stop, other.num))
    def __ne__(self, other):
        return not self==other
    def __hash__(self):
        return hash((type(self), self.start, self.stop, self.num))

2

ভাসমান নির্ভুলতার সমস্যাগুলির মোকাবিলা করতে আপনি Decimalমডিউলটি ব্যবহার করতে পারেন ।

কোডটি কোড Decimalথেকে লেখার সময় intবা floatলেখার সময় এটির অতিরিক্ত প্রচেষ্টা দাবি করে , তবে আপনি যদি পরিবর্তে strফাংশনটি পাস এবং সংশোধন করতে পারেন তবে যদি সেই ধরণের সুবিধার্থে প্রয়োজন হয়।

from decimal import Decimal
from decimal import Decimal as D


def decimal_range(*args):

    zero, one = Decimal('0'), Decimal('1')

    if len(args) == 1:
        start, stop, step = zero, args[0], one
    elif len(args) == 2:
        start, stop, step = args + (one,)
    elif len(args) == 3:
        start, stop, step = args
    else:
        raise ValueError('Expected 1 or 2 arguments, got %s' % len(args))

    if not all([type(arg) == Decimal for arg in (start, stop, step)]):
        raise ValueError('Arguments must be passed as <type: Decimal>')

    # neglect bad cases
    if (start == stop) or (start > stop and step >= zero) or \
                          (start < stop and step <= zero):
        return []

    current = start
    while abs(current) < abs(stop):
        yield current
        current += step

নমুনা আউটপুট -

list(decimal_range(D('2')))
# [Decimal('0'), Decimal('1')]
list(decimal_range(D('2'), D('4.5')))
# [Decimal('2'), Decimal('3'), Decimal('4')]
list(decimal_range(D('2'), D('4.5'), D('0.5')))
# [Decimal('2'), Decimal('2.5'), Decimal('3.0'), Decimal('3.5'), Decimal('4.0')]
list(decimal_range(D('2'), D('4.5'), D('-0.5')))
# []
list(decimal_range(D('2'), D('-4.5'), D('-0.5')))
# [Decimal('2'),
#  Decimal('1.5'),
#  Decimal('1.0'),
#  Decimal('0.5'),
#  Decimal('0.0'),
#  Decimal('-0.5'),
#  Decimal('-1.0'),
#  Decimal('-1.5'),
#  Decimal('-2.0'),
#  Decimal('-2.5'),
#  Decimal('-3.0'),
#  Decimal('-3.5'),
#  Decimal('-4.0')]

2
অনুরূপ Decimalইনপুটগুলির np.arangeসাথে একই কাজ করে:np.arange(Decimal('-2.0'), Decimal('2.0'), Decimal('0.1'))
এইচপিউলজ

2
হ্যাঁ, ধন্যবাদ যদিও, এটির জন্য একটি বাহ্যিক (নম্পি) লিবিব প্রয়োজন।
sha00__wa1k3r

1

পদক্ষেপে একটি ভুল চিহ্নের সম্ভাবনার জন্য স্বতঃ-সংশোধন যুক্ত করুন:

def frange(start,step,stop):
    step *= 2*((stop>start)^(step<0))-1
    return [start+i*step for i in range(int((stop-start)/step))]

1

আমার সমাধান:

def seq(start, stop, step=1, digit=0):
    x = float(start)
    v = []
    while x <= stop:
        v.append(round(x,digit))
        x += step
    return v

1

সেরা সমাধান: গোলাকার ত্রুটি নেই
_________________________________________________________________________________

>>> step = .1
>>> N = 10     # number of data points
>>> [ x / pow(step, -1) for x in range(0, N + 1) ]

[0.0, 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1.0]

_________________________________________________________________________________________

অথবা সেট ডেটার পয়েন্টের (যেমন ক্রমাগত ফাংশন) পরিবর্তে একটি সেট ব্যাপ্তির জন্য ব্যবহার করুন:

>>> step = .1
>>> rnge = 1     # NOTE range = 1, i.e. span of data points
>>> N = int(rnge / step
>>> [ x / pow(step,-1) for x in range(0, N + 1) ]

[0.0, 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1.0]

একটি ফাংশন বাস্তবায়ন করার জন্য: প্রতিস্থাপন x / pow(step, -1)সঙ্গে f( x / pow(step, -1) ), এবং সংজ্ঞায়িত f
উদাহরণ স্বরূপ:

>>> import math
>>> def f(x):
        return math.sin(x)

>>> step = .1
>>> rnge = 1     # NOTE range = 1, i.e. span of data points
>>> N = int(rnge / step)
>>> [ f( x / pow(step,-1) ) for x in range(0, N + 1) ]

[0.0, 0.09983341664682815, 0.19866933079506122, 0.29552020666133955, 0.3894183423086505, 
 0.479425538604203, 0.5646424733950354, 0.644217687237691, 0.7173560908995228,
 0.7833269096274834, 0.8414709848078965]

1

শুরু এবং থামানো এক বা অন্যটির চেয়ে অন্তর্ভুক্ত থাকে (সাধারণত স্টপ বাদ থাকে) এবং আমদানি ছাড়াই এবং জেনারেটর ব্যবহার করে

def rangef(start, stop, step, fround=5):
    """
    Yields sequence of numbers from start (inclusive) to stop (inclusive)
    by step (increment) with rounding set to n digits.

    :param start: start of sequence
    :param stop: end of sequence
    :param step: int or float increment (e.g. 1 or 0.001)
    :param fround: float rounding, n decimal places
    :return:
    """
    try:
        i = 0
        while stop >= start and step > 0:
            if i==0:
                yield start
            elif start >= stop:
                yield stop
            elif start < stop:
                if start == 0:
                    yield 0
                if start != 0:
                    yield start
            i += 1
            start += step
            start = round(start, fround)
        else:
            pass
    except TypeError as e:
        yield "type-error({})".format(e)
    else:
        pass


# passing
print(list(rangef(-100.0,10.0,1)))
print(list(rangef(-100,0,0.5)))
print(list(rangef(-1,1,0.2)))
print(list(rangef(-1,1,0.1)))
print(list(rangef(-1,1,0.05)))
print(list(rangef(-1,1,0.02)))
print(list(rangef(-1,1,0.01)))
print(list(rangef(-1,1,0.005)))
# failing: type-error:
print(list(rangef("1","10","1")))
print(list(rangef(1,10,"1")))

পাইথন 3.6.2 (v3.6.2: 5fd33b5, জুলাই 8 2017, 04:57:36) [এমএসসি v.1900 64 বিট (এএমডি 64)]


1

আমি জানি আমি এখানে পার্টিতে দেরি করেছি, তবে এখানে একটি তুচ্ছ জেনারেটর সমাধান রয়েছে যা 3.6 তে কাজ করছে:

def floatRange(*args):
    start, step = 0, 1
    if len(args) == 1:
        stop = args[0]
    elif len(args) == 2:
        start, stop = args[0], args[1]
    elif len(args) == 3:
        start, stop, step = args[0], args[1], args[2]
    else:
        raise TypeError("floatRange accepts 1, 2, or 3 arguments. ({0} given)".format(len(args)))
    for num in start, step, stop:
        if not isinstance(num, (int, float)):
            raise TypeError("floatRange only accepts float and integer arguments. ({0} : {1} given)".format(type(num), str(num)))
    for x in range(int((stop-start)/step)):
        yield start + (x * step)
    return

তারপরে আপনি এটিকে আসলটির মতোই বলতে পারবেন range()... পরিচালনা করার ক্ষেত্রে কোনও ত্রুটি নেই, তবে যুক্তিযুক্তভাবে ধরা যেতে পারে এমন কোনও ত্রুটি আছে কিনা তা আমাকে জানান এবং আমি আপডেট করব। অথবা আপনি এটি আপডেট করতে পারেন। এটি স্ট্যাকওভারফ্লো।


0

এখানে আমার সমাধান যা ফ্লোট_আরঞ্জ (-1, 0, 0.01) দিয়ে সূক্ষ্মভাবে কাজ করে এবং ভাসমান পয়েন্ট উপস্থাপনের ত্রুটি ছাড়াই কাজ করে। এটি খুব দ্রুত নয়, তবে দুর্দান্ত কাজ করে:

from decimal import Decimal

def get_multiplier(_from, _to, step):
    digits = []
    for number in [_from, _to, step]:
        pre = Decimal(str(number)) % 1
        digit = len(str(pre)) - 2
        digits.append(digit)
    max_digits = max(digits)
    return float(10 ** (max_digits))


def float_range(_from, _to, step, include=False):
    """Generates a range list of floating point values over the Range [start, stop]
       with step size step
       include=True - allows to include right value to if possible
       !! Works fine with floating point representation !!
    """
    mult = get_multiplier(_from, _to, step)
    # print mult
    int_from = int(round(_from * mult))
    int_to = int(round(_to * mult))
    int_step = int(round(step * mult))
    # print int_from,int_to,int_step
    if include:
        result = range(int_from, int_to + int_step, int_step)
        result = [r for r in result if r <= int_to]
    else:
        result = range(int_from, int_to, int_step)
    # print result
    float_result = [r / mult for r in result]
    return float_result


print float_range(-1, 0, 0.01,include=False)

assert float_range(1.01, 2.06, 5.05 % 1, True) ==\
[1.01, 1.06, 1.11, 1.16, 1.21, 1.26, 1.31, 1.36, 1.41, 1.46, 1.51, 1.56, 1.61, 1.66, 1.71, 1.76, 1.81, 1.86, 1.91, 1.96, 2.01, 2.06]

assert float_range(1.01, 2.06, 5.05 % 1, False)==\
[1.01, 1.06, 1.11, 1.16, 1.21, 1.26, 1.31, 1.36, 1.41, 1.46, 1.51, 1.56, 1.61, 1.66, 1.71, 1.76, 1.81, 1.86, 1.91, 1.96, 2.01]

0

আমি কেবল একটি শিক্ষানবিস, তবে কিছু গণনা অনুকরণ করার সময় আমারও একই সমস্যা ছিল। এখানে আমি কীভাবে এটি কাজ করার চেষ্টা করেছি, যা মনে হচ্ছে দশমিক পদক্ষেপ নিয়ে কাজ করছে।

আমিও বেশ অলস এবং তাই আমার নিজের পরিসীমা ফাংশনটি লিখতে আমার পক্ষে শক্ত মনে হয়েছিল।

মূলত আমি যা করেছি তা আমার পরিবর্তিত xrange(0.0, 1.0, 0.01)হয় xrange(0, 100, 1)এবং 100.0লুপের অভ্যন্তরে বিভাগটি ব্যবহার করে । আমিও উদ্বিগ্ন ছিলাম, যদি রাউন্ডিং ভুল হয়। সুতরাং আমি পরীক্ষা করার সিদ্ধান্ত নিয়েছি, কোন আছে কিনা। এখন আমি শুনেছি, উদাহরণস্বরূপ যদি 0.01কোনও গণনা থেকে সঠিকভাবে ভাসা না হয়0.01 তাদের সাথে তুলনা করা তবে মিথ্যা ফিরিয়ে দেওয়া উচিত (যদি আমি ভুল হয়ে থাকে তবে দয়া করে আমাকে জানান)।

সুতরাং আমি সিদ্ধান্ত নিয়েছি যে আমার সমাধানটি একটি ছোট পরীক্ষা চালিয়ে আমার পরিসীমাটির জন্য কাজ করবে কিনা:

for d100 in xrange(0, 100, 1):
    d = d100 / 100.0
    fl = float("0.00"[:4 - len(str(d100))] + str(d100))
    print d, "=", fl , d == fl

এবং এটি প্রতিটি জন্য সত্য মুদ্রিত।

এখন, আমি যদি এটি পুরোপুরি ভুল হয়ে যাচ্ছি তবে দয়া করে আমাকে জানান।


0

এই এক লাইনারটি আপনার কোডটিকে বিশৃঙ্খলা করবে না। পদক্ষেপের প্যারামিটারের চিহ্নটি গুরুত্বপূর্ণ।

def frange(start, stop, step):
    return [x*step+start for x in range(0,round(abs((stop-start)/step)+0.5001),
        int((stop-start)/step<0)*-2+1)]
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.