use List::Util qw(sum); my $total = sum values %$group; my $rnd = rand( $total ); my $runningtot = 0; foreach ( keys %$group ) { if ( $rnd > $runningtot && $rnd <= ( $runningtot + $group->{$_} ) ) { $picked = $_; last; }#if $runningtot += $group->{$_}; }#foreach