所以,我在列表中有一堆单词,这些单词我想计算一些统计数据。我将它们分组为字典,但我想减少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')
答案 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);
}
}