在减少我的python代码的if / else部分时该怎么做以及应该考虑什么?

时间:2018-11-07 19:28:32

标签: python python-3.x python-2.7

所以,我在列表中有一堆单词,这些单词我想计算一些统计数据。我将它们分组为字典,但我想减少if / else代码块,以减少重复。我要考虑什么,如何减少呢?谢谢!

将单词归为一组的统计信息

for word in words:
    if len(word) <= 3:
        num_vowels = 0
        for ch in word:
            if ch in 'aeiou':
                num_vowels = num_vowels + 1
        if num_vowels == 0:
            get_stats('short','no_vowels')
        elif 1 <= num_vowels <= 2:
            get_stats('short','few_vowels')
        else:
            get_stats('short','many_vowels')
     elif 4 <= len(word) <= 7:
        num_vowels = 0
        for ch in word:
            if ch in 'aeiou':
                num_vowels = num_vowels + 1
        if num_vowels == 0:
            get_stats('medium','no_vowels')
        elif 1 <= num_vowels <= 2:
            get_stats('medium','few_vowels')
        else:
            get_stats('medium','many_vowels')
    else:
        num_vowels = 0
        for ch in word:
            if ch in 'aeiou':
                num_vowels = num_vowels + 1
        if num_vowels == 0:
            get_stats('long','no_vowels')
        elif 1 <= num_vowels <= 2:
            get_stats('long','few_vowels')
        else:
            get_stats('long','many_vowels')

3 个答案:

答案 0 :(得分:3)

此代码无重复。另外,我删除了一些多余的比较和元音计数:

for word in words:
    if len(word) <= 3:
        description = "short"
    elif len(word) <= 7:
        description = "medium"
    else:
        description = "long"
    num_vowels = sum(word.count(c) for c in 'aeiou')
    if num_vowels == 0:
        get_stats(description, 'no_vowels')
    elif num_vowels <= 2:
        get_stats(description, 'few_vowels')
    else:
        get_stats(description, 'many_vowels')

答案 1 :(得分:1)

您的问题主要是可分离性之一。单独地,您的if-else块还可以,但是它们会成为问题,因为您已将它们一个个地嵌入另一个中,而您不必这样做,并且应该避免:

def get_description(num_words):
    if (num_words < 4):
        return 'short'
    elif (num_words < 8):
        return 'medium'
    else:
        return 'long'

def get_vowels_description(num_words):
    if (num_words == 0):
        return 'no_vowels'
    elif (num_words < 3):
        return 'few_vowels'
    else:
        return 'many_vowels'

现在,有了这些函数定义,您可以以更具可读性的方式构建主调用:

for word in words:
    num_vowels = sum( [1 for c in list(word) if c in 'aeiou'] )
    return get_stats(get_description(len(word)), get_vowels_description(num_vowels))

如您所见,这更加易于管理,可以让您分别测试每个部件,从而确保它们都能正常工作。实际上,您应该遵循的一条经验法则是,当您看到与其他代码看起来相同的代码(除了输入有所不同)时,就该将其拆分为一个函数/方法了。无论如何,我希望这会有所帮助。

答案 2 :(得分:0)

可能有助于分解单调,您可以分解并分别计算。

@Log
@SpringBootApplication
public class RedisApplication {

    private ApplicationRunner titleRunner(String title, ApplicationRunner rr) {
        return args -> {
            log.info(title.toUpperCase() + ":");
            rr.run(args);
        };
    }

    @Bean
    ApplicationRunner geography(RedisTemplate<String, String> rt) {
        return titleRunner("geography", args -> {
            GeoOperations<String, String> geo = rt.opsForGeo();
            geo.add("Sicily", new Point(13.361389, 38.155556), "Arigento");
            geo.add("Sicily", new Point(15.087269, 37.502669), "Catania");
            geo.add("Sicily", new Point(13.583333, 37.316667), "Palermo");

            Circle circle = new Circle(new Point(13.583333, 37.316667),
                    new Distance(100, RedisGeoCommands.DistanceUnit.KILOMETERS));
            GeoResults<GeoLocation<String>> radius = geo.radius("Sicily", circle);
            radius.getContent().forEach(c -> log.info(c.toString()));
        });
    }

    @Bean
    ApplicationRunner repositories(LineItemRepository  lineItemRepository) {
        return titleRunner("repositories", args -> {
            Long orderId = generateId();

            List<LineItem> itemsList = Arrays.asList(
                    new LineItem(orderId, generateId(), "plunger"),
                    new LineItem(orderId, generateId(), "soup"), 
                    new LineItem(orderId, generateId(), "cofee mug"));

            itemsList.stream().map( lineItemRepository::save).forEach(li -> log.info(li.toString()));
        });
    }

    private Long generateId() {
        long tmp = new Random().nextLong();
        return Math.max(tmp, tmp * -1);
    }

    public static void main(String[] args) {
        SpringApplication.run(RedisApplication.class, args);
    }

    @Data
    @AllArgsConstructor
    @NoArgsConstructor
    @RedisHash("orders")
    public class Order implements Serializable {
        @Id
        private Long Id;

        @Indexed
        private Date when;

        @Reference
        private List<LineItem> lineItems;
    }

    @Data
    @AllArgsConstructor
    @NoArgsConstructor
    @RedisHash("lineItems")
    public class LineItem implements Serializable {
        @Indexed
        private Long orderId;

        @Id
        private Long id;

        private String description;
    }

    interface LineItemRepository extends CrudRepository<LineItem, Long> {

    }

    interface OrderRepository extends CrudRepository<Order, Long> {
        Collection<Order> findByWhen(Date date);
    }
}