Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/355.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
对Python中比较整数符号的函数实现的反馈_Python_Sign - Fatal编程技术网

对Python中比较整数符号的函数实现的反馈

对Python中比较整数符号的函数实现的反馈,python,sign,Python,Sign,我做了一个小函数,给定一个元组,比较这个元组中的所有元素是否具有相同的符号 例如,tuple=[-1,-4,-6,-8]是好的,而[-1,-4,12,-8]是坏的。我不确定我是否已经实现了最智能的实现,所以我知道这是一个值得询问的地方 def check_consistent_categories(queryset): try: first_item = queryset[0].amount if first_item < 0:

我做了一个小函数,给定一个元组,比较这个元组中的所有元素是否具有相同的符号

例如,tuple=
[-1,-4,-6,-8]
是好的,而
[-1,-4,12,-8]
是坏的。我不确定我是否已经实现了最智能的实现,所以我知道这是一个值得询问的地方

def check_consistent_categories(queryset):
    try:
        first_item = queryset[0].amount

        if first_item < 0:
            for item in queryset:
                if item > 0:
                    return False
            return True
        else:
            for item in queryset:
                if item < 0:
                    return False
            return True
    except:
        return False
def检查一致性类别(queryset):
尝试:
第一项=查询集[0]。金额
如果第一项<0:
对于queryset中的项:
如果项目>0:
返回错误
返回真值
其他:
对于queryset中的项:
如果项目<0:
返回错误
返回真值
除:
返回错误
这可能会帮助您:

def all_same_sign(ints):
    return all(x < 0 for x in ints) or all(x > 0 for x in ints)
def所有相同符号(整数):
返回全部(x<0表示x in ints)或all(x>0表示x in ints)

您可能希望将更改为=,具体取决于您希望如何处理0。

这里有一个很好的pythonic方法(使用
all()
):

(对于Python2.6+,它引入了
math.copysign()
函数)。此解决方案认为0为正


然而,马克·拜尔斯的解决方案更灵活,也更易读。

只需一个不相关的nit,因为您正在这样做:

try:
    [...]
except:
    [...]
你忽略了所有的异常,要非常小心,我的朋友,这会隐藏很多错误,而不是在处理异常时始终保持精确,例如:

try:
    [...]
except IndexError:
    # Handle out of index
except IOError:
    # Handle I/O error

等等。在编写更大的python应用程序时,请记住这一点。

如果对数字进行了排序,则只需比较两端。如果没有,您可以对其进行排序:

def same_sign(numbers):
    numbers = sorted(numbers)
    #if numbers[0]==0: return True                Uncomment if you consider 0 positive
    if numbers[0]*numbers[-1]>0: return True
    return False

如果将其更改为
>=0
0,则零将被视为符号中性。我不确定这是否是一个比当前答案更好的实现,但对于大型数据集,它可能更快。

为什么不利用这样一个事实,即如果所有数字都是相同的符号,那么每个数字的绝对值之和将等于每个数字之和的绝对值

def check_sign(queryset):
    return abs(sum(queryset)) == sum(map(abs, queryset))
显示数学细节的示例 案例1:所有数字都有相同的符号

a = (-1, -4, -8)
sum(a) = -13
abs(sum(a)) = 13        # the absolute value of the tuple's sum
map(abs, a) = [1, 4, 8]
sum(map(abs, a)) = 13   # the tuple's sum of each element's absolute value
b = (-1, 4, 8)
sum(b) = 11
abs(sum(b)) = 11        # the absolute value of the tuple's sum 
map(abs, b) = [1, 4, 8]
sum(map(abs, b)) = 13   # the tuple's sum of each element's absolute value
两种方法的结果都是13,因此符号是相同的

案例2:并非所有数字都有相同的符号

a = (-1, -4, -8)
sum(a) = -13
abs(sum(a)) = 13        # the absolute value of the tuple's sum
map(abs, a) = [1, 4, 8]
sum(map(abs, a)) = 13   # the tuple's sum of each element's absolute value
b = (-1, 4, 8)
sum(b) = 11
abs(sum(b)) = 11        # the absolute value of the tuple's sum 
map(abs, b) = [1, 4, 8]
sum(map(abs, b)) = 13   # the tuple's sum of each element's absolute value

这些方法产生不同的数字(11和13),因此符号并不完全相同。

在@EOL的解决方案之后,但不需要列表索引或多次迭代

def all_same_sign(sequence):
    items = iter(sequence)
    try:
        first = items.next() > 0
    except StopIteration:
        return True
    return all((item > 0) == first for item in items)
我也想到了这一点,但没有利用所有/任何短路:

def all_same_sign(sequence):
    return len(set(item > 0 for item in sequence)) <= 1
定义所有相同符号(顺序):

return len(设置(对于序列中的项,项>0))这里还有一个可以很好地处理生成器等

def all_same_sign(ints):
    ints = iter(ints)
    first_is_positive = next(ints) > 0
    return all( (x>0) == first_is_positive for x in ints)
如果
ints
为空,则会出现StopIteration异常


此版本使用负数替换0。如果您希望使用正数分组,请使用
=

原则是,如果数字都相同,则相乘会产生正结果,否则为负

import operator

def all_same_sign(intlist):
    return reduce(operator.mul, intlist) > 0

>>> all_same_sign([-1, -4, -6, -8])
True
>>> all_same_sign([-1, -4, 12, -8])
False
但这不处理零…

def all\u same\u sign(iterable):
def all_same_sign(iterable):
    # Works with any iterable producing any items that can be compared to zero.
    # Iterates through the input no more than once, and this fact is immediately
    # obvious from the code.
    # Exits as soon as a bad combination has been detected.
    pos = neg = zero = False
    for item in iterable:
        if item > 0:
            pos = True
        elif item < 0:
            neg = True
        else:
            zero = True
        # Adjust the following statement if a different
        # treatment of zero is required.
        # Redundant parentheses added for clarity.
        if (pos and neg) or zero:
            return False
    return True
#与任何iterable一起工作,生成任何可与零比较的项。 #在输入中迭代不超过一次,这一事实将立即得到解决 #从代码中可以明显看出。 #检测到错误组合后立即退出。 位置=负=零=假 对于iterable中的项目: 如果项目>0: pos=真 elif项目<0: 负=真 其他: 零=真 #如果出现不同的错误,请调整以下语句 #需要对零进行处理。 #为清晰起见,添加了多余的括号。 如果(正、负)或零: 返回错误 返回真值
+1我一直想知道为什么会有这么多+1:这是有效的、非常清晰的,而且在处理零方面也是灵活的!这个解决方案的美妙之处在于
all()
短路,在遇到
False
结果时停止,并且您使用的是生成器表达式,而不是列表理解,因此此函数最多只对输入列表进行一次完整遍历,可能更少,尽管它看起来正好有两个。很好。这个解决方案需要在iterable中迭代两次。这将适用于列表(或元组,根据提问者的原始意图),但不适用于生成器或流。例如,所有同一符号(iter(范围(-10,10))评估为真。我要感谢所有的贡献者,大多数确实可行,但这一个满足了我的需要。我为代码中的拼写错误、异常的误用以及我错误地使用单词元组而不是列表感到抱歉。所有这些帖子都让我学到了比我来时更多的东西:-)+1来对抗否决票。是的,使用
lambda
并不等于pythonic(虽然EOL的代码中有一个bug:应该是
lambda x:copysign(1,x)
),但这是一个很好的解决方案。谢谢,@delnan。使用
lambda
确实不会使任何解决方案变成pythonic!然而,对这样一个简单的函数使用一行可以说是足够清晰的,因此python就足够了。此外,使用
all()
确实让我觉得这个解决方案是pythonic的,因为
all()
是一个有用且功能强大的Python函数。它可以工作,但Mark Byers更具可读性和易懂性,所以只能得到+0.)<代码>如果:返回真否则:返回假<代码>返回
!而且,与大多数其他解决方案相比,这是非常浪费的(遍历列表3次!)。@delnan:Argh是对的!不知道我在想什么。我已经删除了不必要的return True和return False。@delnan:True与大多数其他解决方案相比,它是浪费的,但一个优点是它可以处理Tcarbruce识别的
iter(范围(-10,10))
案例。(参见马克·拜尔在回答中的评论)对于大数据集来说,速度会慢一些。