【问题标题】:Elegant list of conditions in PythonPython中优雅的条件列表
【发布时间】:2013-11-05 01:49:16
【问题描述】:

为了好玩,我正在为 Python 制作一个单位转换函数。

这是我的代码,到目前为止:

def UnitConverter(number,*units):
    if units == ("feet","inches"):
        return number*12
    elif units == ("ft","yd"):
        return number/3

您可能知道我是如何完成这项工作的。

因为我对优雅、良好的代码实践和整体流程非常着迷,所以除了我的主要问题:我怎样才能有效地检查列表if 语句中的排列数

示例:是否有有效的方法来完成这项工作?

def UnitConverter(number,*units):
    if units == (("feet" or "foot" or "ft."),("inches" or "in" or "in.")):
        return number*12
    elif units == ("ft","yd"):
        return number/3

如果没有,有没有办法重组我的程序,以便有人可以输入三个参数numberunit1unit2,在编码端,我可以有效地包含所有替代拼写每个单元(feet,foot,ft,etc)?

我真的很重视每个人的意见。

谢谢!

【问题讨论】:

  • 你为什么接受*units,然后反复隐式强制它为两个值,而不是仅仅接受fromunit, tounit作为两个单独的参数?
  • 此外,如果 N 比 3 好得多,尝试处理 N 个单位与 N-1 个其他单位的笛卡尔积将意味着大量代码。为什么不分两步执行此操作:从fromunit 转换为某个规范单位,然后从规范单位转换为tounit。那么你只需要 N*2 if 条件而不是 N**2。
  • +1 到 abarnert,除了改成 from_unitto_unit
  • @abarnert 我使用 *units 是因为我最初计划返回用户想要的任意多的转化,即一对多的转化。
  • 这里还有一个建议:(BSD 或 GNU)units 工具几乎完全符合您的要求,它带有一个漂亮、相对易于解析的数据文件 units.lib,它可以用于构建,例如,RemcoGerlich 的答案中使用的字典。

标签: python list python-2.7 conditional-statements conditional-operator


【解决方案1】:

我会选择一个标准的长度单位,比如 m。然后我会有一个字典,为每个其他单位提供一个因素,然后转换:

conversion_factors = {
    'foot': 0.3048,  # Google search '1 foot in m'
    'yard': 0.9144,
    # etc
}

def unit_convert(number, from_unit='m', to_unit='m'):
    m = number * conversion_factor[from_unit]
    return m / conversion_factor[to_unit]

对于同义词(feet、ft 等),您可以制作第二个字典并在第一个字典中查找规范名称:

conversion_factors = { ... }  # as above

synonyms = {
    'feet': 'foot',
    'ft': 'foot',
    ...
}

def unit_convert(number, from_unit='m', to_unit='m'):
    from_unit = synonyms.get(from_unit, from_unit)
    to_unit = synonyms.get(to_unit, to_unit)
    # etc

...或者只是将它们多次放入conversion_factors 字典中:

conversion_factors = {
    'foot': 0.3048,  # Google search '1 foot in m'
    'feet': 0.3048,
    'ft': 0.3048,
    'yard': 0.9144,
    # etc
}

【讨论】:

  • 这正是我写它的方式......但你应该添加一个例子来说明它如何解决 OP 首先遇到的问题:同一个单元的多个名称。只需添加'feet': 0.3048,
【解决方案2】:

使用集合。

foot_units = {"ft.", "feet", "foot"}

然后您可以检查集合中的所有权。

if(units[0] in foot_units):
   ...

除此之外,创建一个用于通用转换元素的 conversion_factor 字典。然后你可以强制进入你的决赛。

inches -> feet -> yards
inches -> feet -> feet

RemcoGerlich 为该步骤提供了一个很好的解决方案。

【讨论】:

  • 如果你想简化这一点,我会使用单个 1D 表将每个单位转换为单个规范单位/从单个规范单位转换,而不是 2D 表,这将组合爆炸(我们都知道这有多混乱)就像 OP 的代码一样。
【解决方案3】:

可能类似于以下内容,使用 in 运算符检查是否包含:

def UnitConverter(number,*units):
    feet = {'feet', 'foot', 'ft.'}
    inches = {'inches', 'in', 'in.'}
    yards = {'yard', 'yd', 'yd.'}
    if units[0] in feet and units[1] in inches:
        return number*12
    elif units[0] in feet and units[1] in yards:
        return number/3

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2019-02-05
    • 2019-01-29
    • 2015-11-19
    • 1970-01-01
    • 1970-01-01
    • 2020-09-04
    • 2012-05-03
    • 1970-01-01
    相关资源
    最近更新 更多