foreach not returning expected results

Your print_r() statement shows that your $wpdb call is returning an array of objects, and you can’t echo an object. (Unless the object has a __toString() method, but stdClass doesn’t.)

You need to get the property you seek from the object, like this: $city->city_ascii.

Also, you shouldn’t echo the content generated by a shortcode. You should instead return the string.

Code edited to use $wpdb->prepare() to protect against SQL injection (per @TomJNowell’s comment).

add_shortcode('citylist',function(){
    global $wpdb;
    $content="";
    $country = $wpdb->prefix . 'worldcities';
    $title = wp_title("",false,'right');
    $args = $wpdb->get_results( 
                $wpdb->prepare(
                   "SELECT city_ascii FROM %s WHERE ranking < 2 AND country = %s",
                   $country,
                   $title
            )
    );
    foreach ($args as $city_ascii=>$city) {
            $content .= esc_html( $city->city_ascii ) . '<br />';
    };
    return $content;
} );