Python'da 5'e (veya başka bir numaraya) yuvarlayın


162

Aşağıdaki gibi yuvarlayabilen yerleşik bir işlev var mı?

10 -> 10
12 -> 10
13 -> 15
14 -> 15
16 -> 15
18 -> 20

Yanıtlar:


304

Python standart bir işlev bilmiyorum, ama bu benim için çalışıyor:

Python 2

def myround(x, base=5):
    return int(base * round(float(x)/base))

Python3

def myround(x, base=5):
    return base * round(x/base)

Yukarıdakilerin neden işe yaradığını görmek kolaydır. 5'e bölünen sayınızın doğru yuvarlanmış bir tam sayı olduğundan emin olmak istiyorsunuz. Yani, biz ilk tam (bunu round(float(x)/5)nereye floatbiz 5 ile çarpın, sonra 5 bölü beri sadece Python2 içinde tabi) de. Nihai dönüşüm intçünkü round()Python 2'de getiri bir kayan nokta değeri.

Fonksiyonu base5 olarak varsayılan bir parametre vererek daha genel yaptım .


3
Sadece tamsayılar ve yuvarlama, o zaman da yapabilirsinizx // base * base
Tjorriemorrie

7
Bu beni paranoyak ama kullanmayı tercih floor()ve ceil()döküm yerine:base * floor(x/base)
user666412

1
@ user666412 math.floorve math.ceilözel bir tabanla kullanıma izin verme, bu nedenle tercih önemsizdir.
Acumenus

48

0.05 gibi tamsayı olmayan değerlere yuvarlama için:

def myround(x, prec=2, base=.05):
  return round(base * round(float(x)/base),prec)

Ben sadece bir arama yapmak ve "yuvarlak (" "myround ("), parametre değerlerini değiştirmek zorunda kalmadan değiştirmek için benim kod yerine bu yararlı buldum.


2
Aşağıdakileri kullanabilirsiniz: def my_round(x, prec=2, base=0.05): return (base * (np.array(x) / base).round()).round(prec) bu da numpy dizilerini kabul eder.
saubhik

23

Sadece ölçeklendirme meselesi

>>> a=[10,11,12,13,14,15,16,17,18,19,20]
>>> for b in a:
...     int(round(b/5.0)*5.0)
... 
10
10
10
15
15
15
15
15
20
20
20

14

'Dinlenmeyi' kaldırmak işe yarar:

rounded = int(val) - int(val) % 5

Değer düzenliyse bir tamsayı:

rounded = val - val % 5

İşlev olarak:

def roundint(value, base=5):
    return int(value) - int(value) % int(base)

Bu cevabı en yakın kesirli değere yuvarlamak için seviyorum. Yani sadece 0,25'lik artışlar istersem.
jarse fasulyesi


9

round (x [, n]): değerler, güç eksi n değerine 10'un en yakın katına yuvarlanır. Eğer n negatifse ...

def round5(x):
    return int(round(x*2, -1)) / 2

10 = 5 * 2 olduğundan, kayan bölme ve 5.0 ile çarpma yerine 2 ile tamsayı bölme ve çarpma kullanabilirsiniz. Biraz kaymayı sevmediğiniz sürece bu çok önemli değil

def round5(x):
    return int(round(x << 1, -1)) >> 1

1
Round () öğesinin yuvarlamayı daha yüksek değerler de dahil olmak üzere 1.0 dışındaki katlara işleyebileceğini göstermek için +1. (Bununla birlikte, bit kaydırma yaklaşımının şamandıralarla çalışmadığını, çoğu programcı için daha az okunabilir olduğunu belirtmiyoruz.)
Peter Hansen

1
@Peter Hansen +1 için teşekkürler. Bit kaydırmanın şamandıralarla çalışması için int (x) değerine sahip olmanız gerekir. En okunabilir değil kabul ve ben kendim kullanmak olmaz, ama ben sadece 2 ve 5 's değil, sadece 1 içeren "saflık" gibi yaptım.
pwdyson

6

Üzgünüm, Alok Singhai'nin cevabı hakkında yorum yapmak istedim, ancak itibar eksikliği nedeniyle bana izin vermiyor = /

Her neyse, bir adım daha genelleştirip gidebiliriz:

def myround(x, base=5):
    return base * round(float(x) / base)

Bu, tamsayı olmayan bazları, örneğin .25veya herhangi bir kesirli tabanı kullanmamızı sağlar.


Lütfen yanıt olarak yorum göndererek yeni kullanıcı kısıtlamalarını atlamaya çalışmayın. Bir nedenden dolayı kısıtlamalar vardır . Bunu neden ve nasıl bazı cevaplar silindi?
Hoşçakal StackExchange

4

Divround'un değiştirilmiş versiyonu :-)

def divround(value, step, barrage):
    result, rest = divmod(value, step)
    return result*step if rest < barrage else (result+1)*step

yani bu durumda divround (değer, 5, 3) kullanıyorsunuz? ya da belki bölme (değer, 5, 2.5)?
pwdyson

tam olarak çevirin (değer, 5, 3).
Christian Hausknecht

4

kullanın:

>>> def round_to_nearest(n, m):
        r = n % m
        return n + m - r if r + r >= m else n - r

Çarpma kullanmaz ve şamandıradan şamandıralara dönüşmez.

10'un en yakın katına yuvarlama:

>>> for n in range(-21, 30, 3): print('{:3d}  =>  {:3d}'.format(n, round_to_nearest(n, 10)))
-21  =>  -20
-18  =>  -20
-15  =>  -10
-12  =>  -10
 -9  =>  -10
 -6  =>  -10
 -3  =>    0
  0  =>    0
  3  =>    0
  6  =>   10
  9  =>   10
 12  =>   10
 15  =>   20
 18  =>   20
 21  =>   20
 24  =>   20
 27  =>   30

Gördüğünüz gibi, hem negatif hem de pozitif sayılar için çalışır. Bağlar (örn. -15 ve 15) daima yukarı doğru yuvarlanır.

5'in en yakın katına yuvarlanan ve farklı bir "temel" için beklendiği gibi davrandığını gösteren benzer bir örnek:

>>> for n in range(-21, 30, 3): print('{:3d}  =>  {:3d}'.format(n, round_to_nearest(n, 5)))
-21  =>  -20
-18  =>  -20
-15  =>  -15
-12  =>  -10
 -9  =>  -10
 -6  =>   -5
 -3  =>   -5
  0  =>    0
  3  =>    5
  6  =>    5
  9  =>   10
 12  =>   10
 15  =>   15
 18  =>   20
 21  =>   20
 24  =>   25
 27  =>   25

2

Birisinin "mali yuvarlamaya" ihtiyacı olması durumunda (her zaman 0,5 tur):

def myround(x, base=5):
    roundcontext = decimal.Context(rounding=decimal.ROUND_HALF_UP)
    decimal.setcontext(roundcontext)
    return int(base *float(decimal.Decimal(x/base).quantize(decimal.Decimal('0'))))

Belgelere göre diğer yuvarlama seçenekleri:

(Sonsuzluk doğru) ROUND_CEILING
(sıfıra doğru) round_down,
(-Infinity doğru) ROUND_FLOOR,
ROUND_HALF_DOWN, (kravat sıfıra doğru gidiyor en yakın)
, (kravat en yakın çift tam gidiş ile en yakın) ROUND_HALF_EVEN
bağları gidiyor en yakın ROUND_HALF_UP ( sıfırdan uzağa) veya
ROUND_UP (sıfırdan uzağa).
ROUND_05UP (sıfıra yuvarlamadan sonraki son basamak 0 veya 5 ise, aksi halde sıfıra)

Varsayılan olarak Python, bazı istatistiksel avantajlara sahip olduğundan ROUND_HALF_EVEN kullanır (yuvarlanmış sonuçlar önyargılı değildir).


2

Tamsayılar için ve Python 3 ile:

def divround_down(value, step):
    return value//step*step


def divround_up(value, step):
    return (value+step-1)//step*step

üreten:

>>> [divround_down(x,5) for x in range(20)]
[0, 0, 0, 0, 0, 5, 5, 5, 5, 5, 10, 10, 10, 10, 10, 15, 15, 15, 15, 15]
>>> [divround_up(x,5) for x in range(20)]
[0, 5, 5, 5, 5, 5, 10, 10, 10, 10, 10, 15, 15, 15, 15, 15, 20, 20, 20, 20]


1

5'in sonraki katı

51'in 55'e dönüştürülmesi gerektiğini düşünün:

code here

mark = 51;
r = 100 - mark;
a = r%5;
new_mark = mark + a;

1

İşte benim C kodum. Eğer doğru anlarsam, bunun gibi bir şey olması gerekirdi;

#include <stdio.h>

int main(){
int number;

printf("Enter number: \n");
scanf("%d" , &number);

if(number%5 == 0)
    printf("It is multiple of 5\n");
else{
    while(number%5 != 0)
        number++;
  printf("%d\n",number);
  }
}

ve bu sadece yuvarlamak yerine 5'in en yakın katına yuvarlar;

#include <stdio.h>

int main(){
int number;

printf("Enter number: \n");
scanf("%d" , &number);

if(number%5 == 0)
    printf("It is multiple of 5\n");
else{
    while(number%5 != 0)
        if (number%5 < 3)
            number--;
        else
        number++;
  printf("nearest multiple of 5 is: %d\n",number);
  }
}

1

Bunu yapmanın başka bir yolu (açık çarpma veya bölme işleçleri olmadan):

def rnd(x, b=5):
    return round(x + min(-(x % b), b - (x % b), key=abs))

-3

int()Geçtiğiniz 0.5numaraya ekleyerek aşağı yuvarlamak yerine yuvarlamayı "kandırabilirsiniz" int().


2
Bu aslında soruya cevap vermiyor
Uri Agassi
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.